2013-02-26 111 views
9

我看到this interesting question其中談到了T聲明在課堂上的水平和同樣的字母T(不同的含義)在方法級別。泛型類型衝突?

所以我做了一個測試。

static void Main(string[] args) 
     { 
      var c = new MyClass<int>(); //T is int 
      c.MyField = 1; 
      c.MyProp = 1; 
      c.MyMethod("2"); 
     } 


     public class MyClass<T> 
     { 
      public T MyField; 
      public T MyProp { get; set; } 
      public void MyMethod<T>(T k) 
      { 
      } 
     } 

由於Eric said,編譯器會發出警告。

但是,嗨,類型安全怎麼了?我假設在方法級別有一個類型安全,但是012xx已經被聲明的類的上下文又如何呢?

我的意思是,如果有人問我,我猜應該有一個錯誤那裏沒有警告

爲什麼編譯器允許這樣做? (我很想聽到合理的答案

+3

我相信這與聲明方法變量的方法大致相同,名稱與已經存在的類字段名稱相同 - 但此方法可行,但編譯器也會警告您 – sll 2013-02-26 09:19:44

+0

您可以擴展「但是,嗨,類型安全性發生了什麼? ?您擔心什麼類型的安全違規行爲? – AakashM 2013-02-26 10:18:31

+0

將'public void MyMethod (T k)'改爲'public void MyMethod(T k)'並且應該有一個錯誤:-) – Carsten 2013-02-26 10:38:58

回答

3

有趣的問題。類型安全性在此保存。行爲類似於全局和局部變量。在MyMethod類型T是明確的。我們也可以創建並返回MyClass的新實例如下:

public class MyClass<T> 
{ 
    public T MyField; 
    public T MyProp { get; set; } 
    public MyClass<T> MyMethod<T>(T k) 
    { 
     return new MyClass<T>(); 
    } 
} 

程序:

static void Main() 
{ 
    var c = new MyClass<int>(); //T is int 
    c.MyField = 1; 
    c.MyProp = 1; 

    var myClass = c.MyMethod("2"); 
    myClass.MyField = "2"; 
    myClass.MyField = "4"; 
} 

沒有編譯錯誤,它不應該是,因爲類型安全能得到保障。程序可以編譯。沒有歧義。

警告應該有,因爲牛逼覆蓋其一流水平對口,有沒有簡單的方法在的MyMethod獲得全球牛逼。它也掩蓋了易讀性。

MSDN說,關於靈活性和良好做法Generic Methods (C# Programming Guide)

如果定義採用相同類型參數作爲包含類的通用方法,編譯器生成,因爲該方法範圍內警告CS0693,爭論爲內部T提供的參數隱藏了爲外部T提供的參數。如果需要靈活地調用泛型類方法,而類型參數不是在實例化類時提供的類型參數,則考慮爲方法的類型參數提供另一個標識符。

2

這不是一個類型安全問題。這只是一個可讀性問題 - 這就是爲什麼它只是一個警告。 (此外,T隱藏外T.)

如果變化的MyMethod()到:

public void MyMethod<T>(T k) 
{ 
    Console.WriteLine(typeof(T).FullName); 
} 

它會打印出System.String你的示例代碼,證明它是獲得正確的類型。