2016-09-19 8 views
0

Ich habe gerade Generics in Dotnet gestartet. Ich habe versucht, über generische Klassen und generische Methode zu lernen, wenn ich verwirrt wurde. Darunter füge ich einen Code ein.Generisches Klassentypargument nicht klar?

class Program 
{ 
    static void Main(string[] args) 
    { 
     Helper<int> helper = new Helper<int>(); 
     helper.helperMethod<string>("hello Ram !"); 
     Console.Read(); 
    }  
} 

public class Helper<T> 
{ 
    public void helperMethod<T>(T input) 
    { 
     Console.WriteLine(input); 
    } 
} 

Wenn eine Instanz der Klasse zu schaffen, wird in der Typargument Helper-Klasse verwendet.

Helper<int> helper = new Helper<int>(); 

was ist der Zweck der „int“, oder jede andere Art Argument in der Klasse zu verwenden, wenn ich selbst eine generische Methode erstellen können. Und wenn beim Erstellen einer generischen Klasse ein Argument type verwendet wird, warum wird im Argument type ein anderer Datentyp verwendet als im Vergleich zur generischen Methode?

+2

Normalerweise würden Sie nicht wie in diesem Fall ein separates generisches Argument für 'helperMethod' deklarieren. Und das macht es verwirrender, weil Sie dann den gleichen * Namen * für das Argument type in dieser Methode verwendet haben, wie Sie es für ein Argument vom Typ class haben. –

+2

In Ihrem Beispiel gibt es keinen Sinn, da das Argument type für die generische Klasse nirgends verwendet wird. Daher können Sie es entfernen. –

Antwort

1

was ist der Zweck der „int“, oder jede andere Art Argument in der Klasse zu verwenden, wenn ich eine generische Methode selbst

diese
  • Um zu verstehen, erstellen können, müssen Sie auf jeden Fall tiefer in erhalten die generics. Idee hinter der generic class or method ist einfach, um jede Art von code bloating zu vermeiden. Da die gleiche Implementierung für mehrere Typen verwendet werden kann, ohne eine separate Implementierung/Überladung für jeden Typ vorzunehmen. Lassen Sie uns verstehen einige Code-Beispiele verwenden:

Dieser Code wird funktionieren, weil T keine Relevanz im HelperMethod hat, Console.WriteLine, nimmt object Basistyp als Eingabe, die für die ganze T

die Basisklasse ist
public class Helper<T> 
{ 
    public void helperMethod<T>(T input) 
    {    
     Console.WriteLine(input); 
    } 
} 

einen Blick auf die Änderungen möglich aussehen lassen:

  1. Fabrikat nur entweder ein method oder class Generika in diesem Fall, da sowohl generische machen, fügt wenig Wert, so etwas wie:
public class Helper<T> 
{ 
    public void HelperMethod(T input) 
    {    
     Console.WriteLine(input); 
    } 
} 

Oder

public class Helper 
{ 
    public void HelperMethod<T>(T input) 
    {    
     Console.WriteLine(input); 
    } 
} 
  1. Noch wichtiger Punkt, dass Generika würdig macht, ist Constraints einzuführen, denn das ist der einzige Weg, sie sinnvoll in wirklichen Sinn machen
public class Helper<T> where T:ICustom 
{ 
    public void HelperMethod(T input) 
    {    
     A a = input.Method1(); 
     B b = input.Method2(); 
    } 
} 

interface ICustom 
{ 
    A Method1(); 

    B Method2();  
} 

Class A 
{ 
    // Fields and Properties of Class A 
} 

Class B 
{ 
    // Fields and Properties of Class B 
}  

Bedeutung Dabei ist der generische Typ kann verwendet werden, um die relevanten Methoden aufzurufen und verwenden Sie die Ausgabe in der generischen Methode, wie A and B Typen im obigen Fall kann wirklich zu Generic implementation führen.

Ein weiterer Bereich, in der Einschränkung ist äußerst nützlich ist so etwas wie Func<T,A>, die es der Benutzer geliefert werden können zu implementieren, so etwas wie:

public class Helper<T> 
{ 
    public void HelperMethod(Func<T,A> input,Func<T,B> input1,T t1) 
    {    
     A a = input(t1); 
     B b = input1(t1); 
    } 
} 

Hier ist die Func Implementierung von Anrufern erfolgen würde, würde aber Ergebnisse gewährleisten wie Type A and B

6

Es gibt zwei nützliche Varianten der Helper Klasse, das wäre klarer, je nach dem gewünschten Effekt:

  1. eine Art Argumente, die nur auf der Klasse

    public class Helper<T> 
    { 
        public void helperMethod(T input) 
        { 
         Console.WriteLine(input); 
        } 
    } 
    

    In diesem Fall Die Main Methode, wie beschrieben, führt zu einem Kompilierungsfehler, da Helper<int>.helperMethod nur int für input akzeptiert.

  2. eine Art Argument, die nur über die Methode

    public class Helper 
    { 
        public void helperMethod<T>(T input) 
        { 
         Console.WriteLine(input); 
        } 
    } 
    

    In diesem Fall kann Helper.helperMethod jede Art annehmen.

1

was ist der Zweck der „int“, oder jede andere Art Argument in der Klasse zu verwenden, wenn ich eine generische Methode erstellen kann selbst

zwecklos. Sie können genauso einfach eine statische Methode zu erstellen, die einen generischen Parameter nimmt:

class Program 
{ 

    static void helperMethod<T>(T input) 
    { 
     Console.WriteLine(input); 
    } 


    static void Main(string[] args) 
    { 
     helperMethod<string>("hello Ram !"); 
     helperMethod<int>(1024); 
     Console.Read(); 
    } 
} 

Ein zusätzlicher Punkt dazu: der C# -Compiler in der Regel intelligent genug, um den Parametertyp für die Funktion, um herauszufinden, ruft wie die oben, so Sie könnten nur schreiben:

helperMethod("hello Ram !"); 
    helperMethod(1024); 

Und auch wenn der Typ Argument verwendet wird, während eine generische Klasse zu schaffen, warum verschiedene Datentypen in Typargument verwendet werden, wie auf generische Methode verglichen?

Das von Ihnen gepostete Beispiel ist zu einfach, um irgendeinen Vorteil dabei zu haben. Sie könnten eine generische Klasse basierend auf einem Typ haben, und sie könnte einen generischen Methodenaufruf haben, der einen anderen Typ verwendet. Dieser Methodenaufruf wäre Teil einer Klasse, die mit Typ T arbeitet, und die Methode selbst nimmt einen Parameter vom Typ Y an. Ein einfaches Beispiel hierfür könnte eine Konverterklasse sein, die verschiedene Typen in den Typ der Klasse konvertiert. d.h .:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var converter = new Converter<string>(); 
     var converted_objected = converter.ConvertThis<int>(200); 
     Console.Read(); 
    } 
} 

class Converter<T> 
{ 
    public T ConvertThis<O>(O to_convert) 
    { 
     T result = default(T); 

     // do stuff with to_convert and the answer ends up in result 

     return result; 
    } 
} 

Ein allzu einfache expample, und es wäre für alle Arten nicht funktionieren, aber ich hoffe, es hilft Ihnen, das Bild zu bekommen.

Grüße,

Adam.