2013-04-23 60 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或從中派生的任何類型。

相關問題