Die Antwort von Oded löst das Problem Kompilierung, so dass Sie die ToDerived Methode definieren, die die Schnittstelle erfüllt. Wie ich im Kommentar gesagt habe, bin ich mir nicht sicher, ob dies die beste Implementierung ist.
Das Hauptproblem habe ich mit ihm ist, dass wie diese Umwandlungsverfahren normalerweise in einem statischen Kontext benötigt werden. Sie haben keine Instanz von SalesUser; Sie wollen einen Benutzer und haben einen Benutzer, also rufen Sie die Methode im statischen Kontext auf (SalesUser.ToDerived(myUser)
) und Sie erhalten einen SalesUser (die Methode würde geeigneterweise FromUser() oder ähnlich genannt werden). Die Methode, die Sie in der Schnittstelle angeben, erfordert, dass Sie bereits einen SalesUser haben, um einen Benutzer in einen SalesUser zu konvertieren. Die einzige Situation, die ich mir vorstellen kann, in der Sie wirklich einen bestehenden SalesUser benötigen, ist ein "partieller Klon"; Sie erstellen eine neue SalesUser-Instanz mit Informationen aus dem übergebenen Benutzer und aus dem SalesUser, auf dem Sie die Methode aufrufen. In allen anderen Fällen benötigen Sie entweder keinen SalesUser (Konvertierungen, die wie erwähnt statisch sein sollten), oder Sie benötigen keinen Benutzer (eine "Klon" - oder "Deep Copy" -Methode, die eine neue Instanz mit dem erzeugt gleiche Daten wie die Instanz, auf der Sie die Methode aufgerufen haben).
Auch die Verbraucher der Klasse müssen wissen, dass sie ToDerived() aufrufen, um muss die Konvertierung von einem Benutzer zu einem SalesUser auszuführen. Normalerweise würde ein C# -Programmierer eine explizite oder implizite erwartet Umwandlung zur Verfügung steht:
public class SalesUser
{
public static explicit operator (User user)
{
//perform conversion of User to SalesUser
}
}
//the above operator permits the following:
mySalesUser = (SalesUser)myUser;
... OR, einen Umwandlungsoperator andernfalls würde man eine SalesUser mit einem Benutzer erwarten zu können, konstruieren:
public class SalesUser:IUser
{
public SalesUser(User user)
{
//initialize this instance using the User object
}
}
//the above allows you to do this:
mySalesUser = new SalesUser(myUser);
//and it also allows the definition of a method like this,
//which requires the generic to be an IUser and also requires a constructor with a User
public void DoSomethingWithIUser<T>(User myUser) where T:IUser, new(User)
{
//...which would allow you to perform the "conversion" by creating a T:
var myT = new T(myUser);
}
nun statische Mitglieder nicht erfüllen Schnittstellendefinitionen und Schnittstellen statische Elemente oder Konstruktor Signaturen nicht definieren können. Dies sagt mir, dass die IUser-Schnittstelle nicht versuchen sollte, die Konvertierungsmethode zu definieren; stattdessen können Methoden, die einen IUser irgendeiner Art benötigen, dies einfach angeben, und der Benutzer kann eine Implementierung bereitstellen, wenn dies erforderlich ist, ohne dass die Implementierung wissen muss, dass sie in sich selbst konvertieren kann. [Hier]
(http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx) ist ein Link zu einem Blog von Eric, der für diese Frage relevant ist. Es enthält sowohl ein Beispiel, das der untenstehenden Antwort sehr ähnlich sieht, als auch Fehler bei der Verwendung dieses Entwurfsmechanismus. – Servy