2016-11-07 65 views
2

是否有可能在C#中執行以下專門化?我可以用C++做到這一點,但不明白如何在C#中實現相同的結果。C#專用泛型類

class GenericPrinter<T> 
{ 
    public void Print() 
    { 
     Console.WriteLine("Unspecialized method"); 
    } 
} 

class GenericPrinter<int> 
{ 
    public void Print() 
    { 
     Console.WriteLine("Specialized with int"); 
    } 
} 

補充:

與建議GenericPrinterInt解決的問題是,我需要明確地創建它。 new GenericPrinter<int>仍將打印Unspecialized method

我想要的是使用這個GenericPrinter從另一個泛型類沒有知識是T等於int或其他東西。

+4

C++模板不是.NET泛型。你不能。 –

+1

下面是一個很好的解釋,甚至解釋了Java泛型的差異:http://stackoverflow.com/questions/31693/what-are-the-differences-between-generics-in-c-sharp-and-java-和 - 模板 - 我。 –

+1

你不能。你需要找到其他方式來處理這種情況。 –

回答

7

我想你可以得到C#中的接近將是:

class GenericPrinter<T> 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("Unspecialized method"); 
    } 
} 

class IntPrinter : GenericPrinter<int> 
{ 
    public override void Print() 
    { 
     Console.WriteLine("Specialized with int"); 
    } 
} 

否則,答案是,你不能專注於C#。

由於Lyubomyr Shaydariv在他的評論中說:

C++模板不是.NET泛型。你不能。


從您的編輯我猜你將有一些類型的檢查,以。

你可以用字典來做這個例子。

class GenericPrinter<T> 
{ 
    private Dictionary<Type, Action> _actions 
     = new Dictionary<Type, Action>() 
    { 
     { typeof(int), PrintInt } 
    }; 

    public virtual void Print() 
    { 
     foreach (var pair in _actions) 
      if (pair.First == typeof(T)) 
      { 
       pair.Second(); 
       return ; 
      } 
     Console.WriteLine("Unspecialized method"); 
    } 

    public virtual void PrintInt() 
    { 
     Console.WriteLine("Specialized with int"); 
    } 
} 

就像你可以看到的,你將不得不爲每種類型做一個方法,你想要處理。當你試圖將T操作爲int時,你也可能遇到一些問題。因爲T確實是通用的(它沒有任何約束),所以它更有可能在代碼中運行爲object(不是在運行時),您將不得不在您的方法中將其轉換爲(int)(object)yourTVariable,在那裏您確定Tint

但是對於這個部分,我想我的一些同齡人會比我給你一個更好的答案。


如果它只是顯示哪種類型使用的是:

public virtual void Print() 
{ 
    Console.WriteLine($"Specialized with {typeof(T).Name}"); 
} 

但你不會有非特消息了(如果你仔細想想,你不能有一個GenericPrinter沒有指定其類型實例化。然後,它是沒有意義的有一個顯示「非專業化」的方法,你將永遠有一個指定類型

無論如何,答案還是一樣,你不能專門在C#中使用泛型。

+2

速度的投票。你快1分鐘。 ;) – Dmitry

+1

@Dmitry :(即使規則禁止這種評論)謝謝:) –

3

在C#中是不可能的。
您可以使用繼承來代替:

class GenericPrinter<T> 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("Unspecialized method"); 
    } 
} 

class GenericPrinterInt : GenericPrinter<int> 
{ 
    public override void Print() 
    { 
     Console.WriteLine("Specialized with int"); 
    } 
} 

根據更新後的問題,我只能建議你使用以下方法。

class GenericPrinter<T> 
{ 
    public static GenericPrinter<T> Create() 
    { 
     if (typeof(int).IsAssignableFrom(typeof(T))) 
      return (GenericPrinter<T>)(object)new GenericPrinterInt(); 

     if (typeof(double).IsAssignableFrom(typeof(T))) 
      return (GenericPrinter<T>)(object)new GenericPrinterDouble(); 

     // Other types to check ... 

     return new GenericPrinter<T>(); 
    } 

    public virtual void Print() 
    { 
     Console.WriteLine("Unspecialized method"); 
    } 
} 

class GenericPrinterInt : GenericPrinter<int> 
{ 
    public override void Print() 
    { 
     Console.WriteLine("Specialized with int"); 
    } 
} 

class GenericPrinterDouble : GenericPrinter<double> 
{ 
    public override void Print() 
    { 
     Console.WriteLine("Specialized with double"); 
    } 
} 

其他一些通用類:

class SomeGenericClass<T> 
{ 
    public readonly GenericPrinter<T> Printer = GenericPrinter<T>.Create(); 
} 

用法示例,如果該類型的標準匹配,就可以創建一個靜態工廠方法,可以在其中檢查T類型和實例化一個合適的專業類:

var intClass = new SomeGenericClass<int>(); 
intClass.Printer.Print(); 
// Output: Specialized with int 

var doubleClass = new SomeGenericClass<double>(); 
doubleClass.Printer.Print(); 
// Output: Specialized with double 

var stringClass = new SomeGenericClass<string>(); 
stringClass.Printer.Print(); 
// Output: Unspecialized method 
+2

與我們之間的一分鐘,我們有完全相同的答案x) –

+1

好吧,由於OP編輯他的帖子,你可以做一些事情不同於我,速度不變。 ;) –