14

In a different StackExchange question, I noticed someone using this prototype:

void DoSomething<T>(T arg) where T: SomeSpecificReferenceType
{
    //Code....
}

Bearing in mind there is only a single type constraint (SomeSpecificReferenceType), what is the difference and advantage of writing it like that, instead of simply:

void DoSomething(SomeSpecificReferenceType arg)
{
    //Code....
}

In both cases, arg will be subject to compile-time type checking. In both cases, the body of the method can safely rely on knowledge that arg is of (or is a descendant of) a specific type that is known at compile time.

Is this a case of an overzealous developer learning about generics before learning about ordinary inheritance? Or is there a legitimate reason why a method signature would be written this way?

  • I barely know C# so this is only a guess, but doesn't this enable more efficient static dispatch instead of dynamic dispatch? – Anton Barkovsky Mar 4 '17 at 11:40
13

Is this a case of an overzealous developer learning about generics before learning about ordinary inheritance?

Yes, it probably is.

Or is there a legitimate reason why a method signature would be written this way?

Maybe. Generally, it'd make more sense if there was a return value that involved T, or another parameter that used T.

But, it's possible that the internals of the code use T (perhaps as an argument to a serializer?) and need to use specifically T and not the constraint class. You'll occasionally see that when the constraint is an interface paired with the new constraint and the guts of the method creates Ts for some reason.

So while it's rare to see the constraint version needed, there are some times when it is. And it's always possible that the method used to need it, but now does not and the developer left it as is to not introduce a breaking change.

1

I think I remember myself typing an answer containing this.

At that time the reason was like this:
(The code may be different. Just to illustrate one of the possible reasons why there's a constraint on the type parameter in a generic method.)

class SomeSingleton
{
    static Dictionary<Type, List<object>> staticTypeSpecificList;
    public void AddObjectToList<T>(T t) where T : SomeCommonThing
    {
        Type tt = t.GetType();
        List<object> list;
        if (!staticTypeSpecificList.TryGet(tt, out list))
        {
            list = new List<object>();
            staticTypeSpecificList.Add(tt, list);
        }
        list.Add(t);
    }
}

Basically, the code gets into manually coding type manipulations itself. It might also be mixed up with some reflection stuff.

For example, by using Method<T>(T arg) where T : ..., one can replace arg.GetType() with typeof(T). Though, I don't know whether that choice is good or bad.

I guess this is just an example of the author (possibly me, or someone else) not carefully thinking through all of the possibilities of coding, at the same time focusing too much on a different question/issue.

  • "one can replace arg.GetType() with typeof(T)". This is useful when arg can validly be null, E.g. in some serialization cases. – walpen Mar 1 '17 at 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.