繁体   English   中英

c#泛型基类的具体实现的工厂

[英]c# Factory for concrete implementation of generic base class

我有一个通用的基类。 我有一个实现基类的具体类。

我将如何创建一个工厂类/方法来提供不同类型的具体类?

这里有一个例子:

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 似乎不可能,因为编译器只想要类作为约束,而不是接口。 第二个问题是我无法将 SpecialReceiver 转换为 T。

那么有没有办法让这个工作?

=== 编辑:根据第一个答案添加示例 ===

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(""); 我想这样: ReceiverFactory.Create("SpecialReceiver");

您可以在工厂中使用泛型方法:

class Program
{
    static void Main(string[] args)
    {
        var own = ReceiverFactory.Create<OwnInterpreter>();
        var other = ReceiverFactory.Create<OtherInterpreter>();
        own.Start();
        other.Start();
        Console.ReadLine();
    }
}
interface IInterpreter
{
    void DoSomething();
}

class OwnInterpreter : IInterpreter
{
    public void DoSomething() { Console.WriteLine("Own"); }
}

class OtherInterpreter : IInterpreter
{
    public void DoSomething() { Console.WriteLine("Other"); }
}

abstract class ReceiverBase<T> where T: IInterpreter, new()
{
    public T Interpreter { get; set; }
    public ReceiverBase()
    {
        Interpreter = new T();  
    }
    public void Start()
    {
        Interpreter.DoSomething();
    }
}

class SpecialReceiver : ReceiverBase<OwnInterpreter> { }
class OtherReceiver : ReceiverBase<OtherInterpreter> { }

static class ReceiverFactory
{
    private static Dictionary<string, object> factories = new Dictionary<string, object>();
    static ReceiverFactory()
    {
        RegisterFactory(() => new SpecialReceiver());
        RegisterFactory(() => new OtherReceiver());
    }
    public static void RegisterFactory<T>(Func<ReceiverBase<T>> factory) where T : IInterpreter, new()
    {
        factories.Add(typeof(T).FullName, factory);
    }
    public static ReceiverBase<T> Create<T>() where T : IInterpreter, new()
    {
        var type = typeof(T);
        return ((Func<ReceiverBase<T>>)factories[type.FullName]).Invoke();
    }
}

事实上,这里不需要“new()”约束,因为你使用了工厂。

我建议您将代码更改为:

    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>();
            }
        }
    }

在您的情况下,您不能只返回T的原因是, SpecialReceiverReceiverBase<IInterpreter>之间没有隐式转换。

我能够找到适合我需求的解决方案。 我添加了另一个接口 IReciver,它定义了我真正需要的属性和成员。 工厂方法返回 IReceiver,因此我可以忽略泛型的所有绑定问题。 有时就是这么简单。 :)

public interface IInterpreter { }

public interface IReceiver
{
    bool Enabled { get; set; }
}

public class OwnInterpreter : IInterpreter
{
    public void DoSomething() { }
}

public abstract class ReceiverBase<T> : IReceiver
    where T : IInterpreter, new()
{
    public T MyReceiver { get; set; }

    internal abstract void Start();

    private bool _isEnabled;
    public bool Enabled { get { return _isEnabled; } set { _isEnabled = value; OnEnable(value); } }

    internal abstract void OnEnable(bool isEnabled);

    protected ReceiverBase()
    {
        MyReceiver = new T();
    }
}

public class SpecialReceiver : ReceiverBase<OwnInterpreter>
{
    public void CheckSomething()
    {
        MyReceiver.DoSomething();
    }

    internal override void Start()
    {
        // just for testing puropses
        MyReceiver = new OwnInterpreter();
    }

    internal override void OnEnable(bool isEnabled)
    {
        MyReceiver = isEnabled ? new OwnInterpreter() : null;
    }
}

public class ReceiverFactory
{
    public static IReceiver Create(string type)
    {
        switch (type)
        {
            default:
                return new SpecialReceiver();
        }
    }
}

public class Program
{
    [STAThread]
    public static void Main()
    {
        ReceiverFactory.Create("");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM