以下代码是否适用于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'不包含'Name'的定义,也没有扩展方法'Name'接受类型'T'的第一个参数(你是否缺少using指令或汇编引用?)
答案 0 :(得分:3)
您需要对泛型类型T
设置约束 - 否则编译器应该如何知道呢?
制作Ifoo
,然后
do_something<T>(T t) where T : IFoo
interface IFoo
{
string Name {get;set;}
}
答案 1 :(得分: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_Foo
来自Foo
,那么您可以将其约束为类类型,相同的语法:
static void do_something<T>(T t) where T : Foo
{
string n = t.Name;
}
答案 2 :(得分:0)
如果do_something应该总是使用Foo或从Foo派生的任何东西(而不是总是有一个名为Name的属性),你可以这样做:
static void do_something<T>(T t) where T : Foo
{
string n = t.Name;
}
这会将传入的Type约束为Type Foo或从中派生的任何类型。