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)