2013-02-26 9 views
9

Ich sah this interesting question, die über T Deklaration auf Klassenebene und den gleichen Buchstaben T (unterschiedliche Bedeutung) auf Methodenebene spricht.Generische Artkonflikte?

Also habe ich einen Test gemacht.

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) 
      { 
      } 
     } 

Wie Eric said warnt der Compiler warnen.

Aber Hey, was ist mit Sicherheit eingeben? Ich nehme an, es gibt eine Art Sicherheit bei der Methodenebene, aber was ist mit der globalen Kontext der Klasse, in der T bereits deklariert wurde.

Ich meine, wenn jemand mich gefragt haben würde, hätte ich denke, es sollte ein Fehler dort und keine Warnung.

Warum der Compiler dies erlaubt? (Ich würde gerne eine vernünftige Antwort hören)

+3

Ich glaube, das ist fast das selbe wie deklarieren Methodenvariable mit dem gleichen Namen wie bereits bestehenden Klasse Feldname - das funktioniert, aber Compiler warnen Sie auch – sll

+0

Könnten Sie auf "Aber Hey, was passiert, um Sicherheit eingeben?" ? Welche Art von Sicherheitsverletzung, wenn überhaupt, betrifft Sie? – AakashM

+0

Ändere 'public void MyMethod (T k) 'in' public void MyMethod (T k) 'und es sollte ein Fehler sein :-) – Carsten

Antwort

3

Interessante Frage. Typ Sicherheit ist hier erhalten. Verhalten ist vergleichbar mit globalen und lokalen Variablen. In MyMethod Typ T ist eindeutig. Wir können auch neue Instanz von MyClass erstellen und das Rück wie folgt:

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

Das Programm:

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"; 
} 

Es gibt keine Kompilierungsfehler und es sollte nicht sein, weil die Typsicherheit erhalten bleibt. Programm kann kompiliert werden. Es gibt keine Zweideutigkeit.

sollte die Warnung da sein, weil T Gegenstück seiner Klasse Ebene überschreibt und es gibt keine einfache Möglichkeit, in MyMethod, dass die globalen T zu erhalten. Es verschleiert auch die Lesbarkeit.

MSDN sagt über Flexibilität und gute Praxis in Generic Methods (C# Programming Guide):

Wenn Sie eine generische Methode definieren, die die gleiche Art Parameter wie die enthaltende Klasse nimmt, der Compiler, weil innerhalb der Methode Umfang Warnung CS0693 generiert, das Argument Wenn Sie die Flexibilität für den Aufruf einer generischen Klassenmethode mit anderen Typargumenten als den beim Instanziieren der Klasse bereitgestellten Argumenten benötigen, sollten Sie in Erwägung ziehen, eine andere Kennung für den Typparameter der Methode anzugeben .

2

Dies ist kein Sicherheitsproblem. Es ist nur ein Lesbarkeitsproblem - deshalb ist es nur eine Warnung. (Auch versteckt T die äußere T.)

Wenn Änderung MyMethod() auf:

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

Es wird für Ihre Beispielcode auszudrucken System.String, was beweist, dass es die richtige Art erhält.

Verwandte Themen