C# 为什么这个泛型类没有像泛型方法那样拾取提供的类型?

C# 为什么这个泛型类没有像泛型方法那样拾取提供的类型?,c#,generics,nested-generics,C#,Generics,Nested Generics,考虑以下静态通用方法: public class Foo { public static void Test<T>(T arg) where T : FrameworkElement { } } 但是,对于以下泛型类 public class Laa<T> where T : FrameworkElement { public Laa(T element) { } } 相反,我必须像这样显式地提供类型 var m

考虑以下静态通用方法:

public class Foo
{
    public static void Test<T>(T arg)
    where T : FrameworkElement
    {
    }
}
但是,对于以下泛型类

public class Laa<T>
where T : FrameworkElement
{
    public Laa(T element)
    {
    }
}
相反,我必须像这样显式地提供类型

var myButton = new Button();
var laa = new Laa<Button>(myButton);
var myButton=new Button();
var laa=新laa(myButton);
我以为所提供的参数会暗示
T
,但事实似乎并非如此

我怀疑原因是因为没有类
Laa
——这个类实际上是
Laa
——所以它不知道要构造什么,但这只是一个猜测


即便如此,编译器还没有足够的信息来解决这个问题吗?没有类
Laa
,但是有一个通用的
Laa
,可以满足提供的参数。

没关系。您必须始终在构造函数中声明泛型类型。第一个示例调用静态方法,而不是类。你永远不能叫一个班。第二个示例调用该类的构造函数。泛型类的实例化需要泛型类型声明

考虑这一点:

public class Laa<T>
where T : FrameworkElement
{
    public Laa(T element)
    {
    }

    public void Foo<U>(U element)
    {
    }
}

var x = new Laa<Button>(button);
x.Foo(button);
公共类Laa
其中T:FrameworkElement
{
公共Laa(T元件)
{
}
公共无效Foo(U元素)
{
}
}
var x=新的Laa(按钮);
x、 Foo(按钮);

在本例中,Foo是一个方法,您不必声明该方法的泛型部分。方法可以推断泛型类型。构造函数不能。这是C编译器的一个已知限制。有一些计划在VS2015中修复它,但该功能已被删除。它可能在将来某个时候得到修复。关于构造函数中的类型推断的最好解释可能可以在本文中找到-一个很好的解决方法是在非泛型类中使用静态工厂方法,如
Tuple.Create()
我认为这不是一个合适的示例,因为代码中的“Foo”不是您所说的方法。方法不需要返回类型或void。您显示了一个命名错误的构造函数。此外,由于您已经通过构造函数定义了“T”,即使这是一个方法,调用“Foo”时也不会暗示它的值,因为它之前已经键入过。在您的示例中,
Foo
“知道”该类型,因为它是在
Laa
的实例上调用的,而不是因为您传递了
按钮。也许你想把它定义为
公共void Foo(U元素)
?对不起,我的错。只是打字错误。当然,应该有一个返回类型/void。@juharr是的,但这与“static”示例完全相同。简单地说,构造函数不能归纳泛型类型,方法可以。我们可以对此进行争论,但遗憾的是,这就是我们所能做的一切。我只是说,在您的示例中,该方法没有使用推断类型,因为泛型类型位于类上,它是在创建类时确定的,而不是在调用该方法时确定的。简而言之,
Foo
方法不是泛型的,包含它的类是泛型的。
var myButton = new Button();
var laa = new Laa<Button>(myButton);
public class Laa<T>
where T : FrameworkElement
{
    public Laa(T element)
    {
    }

    public void Foo<U>(U element)
    {
    }
}

var x = new Laa<Button>(button);
x.Foo(button);