私はジェネリックなBaseクラスを持っています。 私は基本クラスを実装する具象クラスを持っています。c#ジェネリックベースクラスの具体的な実装のための工場
さまざまな種類の具象クラスを提供するためのファクトリクラス/メソッドを作成するにはどうすればよいですか?ここで
例:
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();
}
}
}
問題はReceiverBaseコンパイラが唯一の制約はなく、インターフェイスとしてクラスを望んでいるので、可能ではないと思われることです。 2番目の問題は、SpecialReceiverをTに変換できないということです。
これを実行する方法はありますか?
=== EDIT:最初の回答に係る実施例を追加しました===
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>();
}
}
}
問題は:MyReceiver.DoSomething();動作しないでしょう。 さらに、私はこのような工場を呼び出す必要があります:ReceiverFactory<OwnInterpreter>.Create("");
私はそのようにしたいのです:
public class ReceiverBase<T> where T : IInterpreter
{
}
public interface IInterpreter
{
}
public class SpecialReceiver<T> : ReceiverBase<T>
where T : IInterpreter
{
}
public class OwnInterpreter : IInterpreter
{
}
public class ReceiverFactory<T> where T : IInterpreter, new()
{
public ReceiverBase<T> Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver<T>();
}
}
}
あなたがいないだけでできる理由を:ReceiverFactory.Create("SpecialReceiver");
あなたの最初のコメントはまったく真実ではありません。あなたは確かに制約としてインターフェイスを持つことができます。しかし、あなたが経験していることは、制約されている型のインスタンスを '新しくできるようにするために、' new() '制約を含める必要があるということです。 –
コンパイラは言う:タイプIInterpreterはパラメータTとしてそれを使用するためにパブリックなパラメータレスコンストラクタを持っている必要があります。コンパイラはこの行を参照します:T:ReceiverBase、new() –
DARKHalf
OK、私は訂正されました。あなたは制約としてインターフェイスを持つことができますが、この場合は 'new()'を使いたいので、そのコンストラクタが存在することを保証する必要があります。インタフェースはコンストラクタを保証しません。 –