在编译时将一个泛型类传递给函数
问题描述:
下面的代码可以在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”的第一个参数可能是一个定义找到了(您是否缺少使用指令或程序集引用?)
答
您需要对通用类型T
设置约束 - 否则编译器应该如何知道它?
做一个Ifoo
然后
do_something<T>(T t) where T : IFoo
interface IFoo
{
string Name {get;set;}
}
答
没有,这个代码将不能在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_Foo
从Foo
导出您可以将其约束到类类型相反,同样的语法:
static void do_something<T>(T t) where T : Foo
{
string n = t.Name;
}
答
如果do_something应始终以富或富(而不仅仅是总有一个属性称为名称)得出任何东西,你可以这样做:
static void do_something<T>(T t) where T : Foo
{
string n = t.Name;
}
这是约束传入的类型为Foo或从中派生的任何类型。
好吧,既然你试过了,清楚地得到了一个编译器错误,答案是“不”。因此,你已经回答了你自己的问题,下面的代码将不起作用。也许你应该解释你想要做什么,并问如何实现这个目标,而不是问你已经回答的问题。 – Servy 2013-04-23 18:09:58