2013-04-23 69 views
0

下面的代码可以在c#中工作吗?在编译时将一个泛型类传递给函数

public class Foo 
{ 
    public string Name { get; set; } 
} 

public class Related_Foo 
{ 
    public string Name { get; set; } 
} 

class Program 
{ 
    static void do_something<T>(T t) 
    { 
     string n = t.Name; 
    } 

    static void Main(string[] args) 
    { 
     Foo f = new Foo(); 

     do_something(f); 
    } 
} 

在.NET 4中,所述编译器抱怨:

“T”不包含“名称”和没有扩展方法“名称”接受类型“T”的第一个参数可能是一个定义找到了(您是否缺少使用指令或程序集引用?)

+0

好吧,既然你试过了,清楚地得到了一个编译器错误,答案是“不”。因此,你已经回答了你自己的问题,下面的代码将不起作用。也许你应该解释你想要做什么,并问如何实现这个目标,而不是问你已经回答的问题。 – Servy 2013-04-23 18:09:58

回答

3

您需要对通用类型T设置约束 - 否则编译器应该如何知道它?

做一个Ifoo然后

do_something<T>(T t) where T : IFoo 

interface IFoo 
{ 
    string Name {get;set;} 
} 
0

没有,这个代码将不能在C#中工作,因为没有什么约束型T有一个叫Name属性。 C#中的模板与C++中的模式不同,编译器可以在编译时扩展它们,并验证实际使用的某些成员是否存在。

若要使其工作,您可以添加一个约束,T必须是具有名为name属性的类型。例如创建一个接口:

public interface IFoo 
{ 
    string Name { get; } 
} 

并让你的类实现这个接口。

那么约束添加到您的方法如下:

static void do_something<T>(T t) where T : IFoo 
{ 
    string n = t.Name; 
} 

如果所有的类都具有属性Name公共基类,例如,如果Related_FooFoo导出您可以将其约束到类类型相反,同样的语法:

static void do_something<T>(T t) where T : Foo 
{ 
    string n = t.Name; 
} 
0

如果do_something应始终以富或富(而不仅仅是总有一个属性称为名称)得出任何东西,你可以这样做:

static void do_something<T>(T t) where T : Foo 
{ 
     string n = t.Name; 
} 

这是约束传入的类型为Foo或从中派生的任何类型。

相关问题