Generisch mit mehreren Klassen

Generisch mit mehreren Klassen

Zunächst Ihr Code, der versucht, zwei Typbeschränkungen für den generischen Parameter T1 festzulegen kompiliert nicht

where T1 : Supplier, new()
where T1 : Employee, new()

mit folgendem Fehler:

Wie im MSDN-Artikel angegeben, können Sie nur einen where verwenden Einschränkung für jeden generischen Parameter (siehe http://msdn.microsoft.com/en-us/library/bb384067.aspx).

Sie können auch nicht mehrere Klassennamen in eine 'where'-Einschränkung einfügen. Nur ein Klassenname und mehrere Schnittstellen.

where T1 : Supplier, IContractor, IComparable, new()

Denken Sie daran, dass diese Einschränkung vorschreibt, dass Sie den tatsächlichen Typ als generischen Parameter T1 angeben muss ein Nachfolger des Supplier sein Klasse oder Supplier Klasse selbst UND sie muss sowohl IContractor implementieren UND IComparable Schnittstellen.

Sobald Ihre Methode einen MyEntity akzeptiert Objekt und Sie geben nicht an, in welcher Beziehung es zu Employee steht und Supplier Klassen, ich kann nicht erraten, wie dieser MyEntity Klasse kennt Employee und Supplier Klassen und wie Ihnen diese Beziehung hilft.

Das einzige, was ich vorschlagen kann, ist, entweder eine Schnittstelle oder eine Basisklasse zu erstellen und beide Klassen davon zu erben. Dies ist der einzige gute Grund, den ich sehe, um eine generische Methode zu erstellen. Das könnte so aussehen:

class Program
{
    static void Main(string[] args)
    {
        Method1<Employee>();
        Method1<Supplier>();
    }

    private static void Method1<T1>()
        where T1 : IContractor, new()
    {

    }
}

public class Supplier : IContractor
{
    string IContractor.Name
    {
        get{return "Supplier-Mufflier";}
    }
}

public class Employee : IContractor
{
    string IContractor.Name
    {
        get{return "Employee-Merloyee";}
    }
}

public interface IContractor
{
    string Name
    {
        get;
    }
}

Wenn Ihre Klassen Supplier und Employee nichts Wichtiges gemeinsam haben, das ausreicht, um eine gemeinsame Schnittstelle zu erstellen, die sie implementieren könnten, sollten Sie keine generische Methode für ihre Verarbeitung erstellen.

Erstellen Sie eine überladene Methode für jeden dieser Typen.

Stellen Sie sich vor, Sie haben zwei Klassen:Wife und Wine . Beide haben ein Attribut von Age und auch vom gleichen Typ. Aber denken Sie nicht einmal daran, eine gemeinsame Schnittstelle IAged zu erstellen für diese Klassen. Das Wesen der Klassen und die Bedeutung des Age ist so unterschiedlich, dass man sie niemals vereinheitlichen sollte. Trotzdem könnte Ihnen eine gemeinsame Logik perfekt dienen. Zum Beispiel:

private double AgeQualify(Wife someWife)
{
    return 1 / (someWife.Age * someWife.Beachness);
}

private double AgeQualify(Wine someWine)
{
    return someWine.Age / someWine.Sugar;
}

Sie müssen entweder separate Versionen erstellen:

private string ConcatenateText<T1, T2>(MyEntity myEntity) 
    where T1 : Supplier, new()
    where T2 : SupplierDepartment, new()  
{
    T1 p = new T1();
    T2 r = new T2();
    return mystring;
}

private string ConcatenateText<T1, T2>(MyEntity myEntity) 
    where T1 : Employee, new()
    where T2 : EmployeeDepartment, new()
{
    T1 p = new T1();
    T2 r = new T2();
    return mystring;
}

oder müssen sie dazu bringen, eine Basisklasse gemeinsam zu nutzen:

private string ConcatenateText<T1, T2>(MyEntity myEntity) 
    where T1 : EmployeeSuplierBase, new()
    where T2 : EmployeeSupplierDeparmentBase, new()
{
    T1 p = new T1();
    T2 r = new T2();
    return mystring;
}

Ich würde die separaten Versionen wirklich bevorzugen, weil sie es mit Supplier nicht aufrufen können und EmployeeDeparment (oder umgekehrt)