Ich habe eine Basisklasse, die generisch ist. Ich habe eine konkrete Klasse, die die Basisklasse implementiert.C# Factory für die konkrete Implementierung der generischen Basisklasse
Wie würde ich eine Factory-Klasse/Methode für die Lieferung verschiedener Arten von Betonklassen erstellen?
Hier ein Beispiel:
public class ReceiverBase<T>
where T : IInterpreter
{ ... }
public class SpecialReceiver : ReceiverBase<OwnInterpreter> { ... }
public class ReceiverFactory<T>
where T : ReceiverBase<IInterpreter>, new()
public T Create(string type) {
switch(type) {
default:
return new SpecialReceiver();
}
}
}
Das Problem ist, dass ReceiverBase nicht möglich zu sein scheint, da die Compiler nur Klassen als Constraints wollen, nicht-Schnittstellen. Und das zweite Problem ist, dass ich SpecialReceiver nicht in T konvertieren kann.
Also gibt es eine Möglichkeit, das funktioniert zu bekommen?
=== EDIT: Hinzugefügt Beispiel gemäß erste Antwort ===
public interface IInterpreter
{
}
public class OwnInterpreter : IInterpreter
{
public void Dispose()
{
throw new NotImplementedException();
}
public void DoSomething() { }
}
public abstract class ReceiverBase<T>
where T : IInterpreter
{
public T MyReceiver { get; set; }
internal abstract void Start();
}
public class SpecialReceiver<T> : ReceiverBase<T>
where T : IInterpreter, new()
{
public void CheckSomething()
{
MyReceiver.DoSomething();
}
internal override void Start()
{
MyReceiver = new T();
}
}
public class ReceiverFactory<T>
where T : IInterpreter, new()
{
public static ReceiverBase<T> Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver<T>();
}
}
}
Das Problem ist: MyReceiver.DoSomething(); wird nicht funktionieren. Außerdem hätte ich das Werk so nennen: ReceiverFactory<OwnInterpreter>.Create("");
ich möchte es haben auf diese Weise: ReceiverFactory.Create("SpecialReceiver");
Ihr erster Kommentar ist überhaupt nicht wahr. Sie können sicherlich Schnittstellen als Einschränkungen haben. Was Sie jedoch erleben können, ist, dass Sie, weil Sie in der Lage sein wollen, neue Instanzen des Typs, der eingeschränkt ist, in der Lage sind, die Einschränkung "new()' einzuschließen, wie Sie haben. –
Compiler sagt: Der Typ IInterpreter muss einen öffentlichen parameterlosen Konstruktor haben, um ihn als Parameter T zu verwenden. Der Compiler bezieht sich auf diese Zeile: wo T: ReceiverBase, new() –
DARKHalf
OK, ich bin korrigiert. Sie * können * Interfaces als Constraints haben, aber in diesem Fall können Sie nicht, weil Sie 'new()' verwenden wollen, und Sie müssen garantieren, dass der Konstruktor existiert. Schnittstellen garantieren keine Konstruktoren. –