2

Let's say that I have the following generic class:

public class Control<TItem>
{
    public Control(TItem item)
    {
    }
}

When I try to pass an object of anonymous type to the constructor, the compilation fails:

var objectOfAnonymousType = new { Foo = "bar" };

// cannot compile:
var control1 = new Control(objectOfAnonymousType);

However if I do this not through the constructor, but through a generic method outside the class, it seems to work:

// can compile:
var control2 = CreateControl(objectOfAnonymousType);

Factory method used:

static Control<TItem> CreateControl<TItem>(TItem item)
{
    return new Control<TItem>(item);
}

I cannot understand the reasoning behind this limitation. Anybody can explain?

Tom Pažourek
  • 9,582
  • 8
  • 66
  • 107
  • http://stackoverflow.com/questions/45604/why-doesnt-c-sharp-support-implied-generic-types-on-class-constructors, http://stackoverflow.com/questions/280172/create-generic-class-instance-based-on-anonymous-type, http://stackoverflow.com/questions/3570167/why-cant-the-c-sharp-constructor-infer-type – CodeCaster Jan 08 '15 at 22:08
  • The error message you get should be fairly descriptive as to what the problem is. – Servy Jan 08 '15 at 22:08
  • This actually has nothing to do with anonymous types at all. This wouldn't work with a regular class type, either, since constructors don't support generic type inference. See the answer by @servy. – Kyle Jan 08 '15 at 22:14
  • @CodeCaster: Thanks for the suggestions with relevant questions, I am voting to close as the duplicate to 280172, which seems to be what I was looking for and haven't seen. – Tom Pažourek Jan 08 '15 at 22:15
  • 1
    @Kyle The difference is that with a named type you would be able to explicitly provide the generic argument. It wouldn't be as concise, but it could be made to work. With anonymous types the problem becomes *impossible* rather than just more verbose. – Servy Jan 08 '15 at 22:15
  • @Kyle: With regular class type I can just write the generic type specification. With anonymous I cannot write . – Tom Pažourek Jan 08 '15 at 22:15
  • 1
    The reason is _"because overload resolution for constructors works differently than for methods, and supporting type inference for constructors didn't make it into the language"_ is what I read in [Why can't the C# constructor infer type?](http://stackoverflow.com/questions/3570167/why-cant-the-c-sharp-constructor-infer-type), especially for deciding which type to pick when _"two types [..] have the same name but different generic arity"_. – CodeCaster Jan 08 '15 at 22:17
  • When I look at C# 6, I have to wonder what are the priorities of the C# language team. I guess consistency across the language isn't that important. – Tom Pažourek Jan 08 '15 at 22:21
  • 1
    @tomp Note that Eric Lippert made comment about similar remark already in http://stackoverflow.com/questions/3570167/why-cant-the-c-sharp-constructor-infer-type#comment-3743990 by saying that there plenty other missing inferences (and there is [article](http://blogs.msdn.com/b/ericlippert/archive/2012/03/09/why-not-automatically-infer-constraints.aspx) talking about some of possible cases). Basically C# is not primarily functional language so the fact that this particular feature is not high priority is not very surprising. – Alexei Levenkov Jan 08 '15 at 22:43

1 Answers1

4

Constructors do not support have generic type inference (yet). They require you to explicitly list out the generic argument for the type. You cannot possibly do that when the generic argument is an anonymous type, even if you wanted to.

Generic methods support type inference of their generic arguments. It's not always possible, but it often is, as is the case here.

Servy
  • 202,030
  • 26
  • 332
  • 449