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”类型的第一个参数的扩展方法“名称”(您是否缺少 using 指令或程序集引用?)

4

3 回答 3

3

您需要对泛型类型施加约束T- 否则编译器应该如何知道它?

做一个Ifoo然后

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

interface IFoo
{
    string Name {get;set;}
}
于 2013-04-23T18:07:54.757 回答
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,例如 ifRelated_Foo是从Foo您派生的,则可以将其限制为类类型,语法相同:

static void do_something<T>(T t) where T : Foo
{
    string n = t.Name;
}
于 2013-04-23T18:10:07.793 回答
0

如果 do_something 应该总是采用 Foo 或任何从 Foo 派生的东西(而不是总是有一个名为 Name 的属性),你可以这样做:

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

这将传入的 Type 限制为 Foo 类型或从它派生的任何类型。

于 2013-04-23T18:17:12.423 回答