使用枚举值创建泛型类型

时间:2016-04-26 11:52:38

标签: c# .net generics design-patterns enums

我希望能够使用枚举值创建新的泛型类型。我相信这可以用C ++模板,但我不知道是否可以用C#。

所以我想做的是:

public class MyClass <T>
{
  public void Do<T>() {} 
}

public enum Metals
{
  Silver, Gold
}

我想传入一个类似的枚举:

var myGoldClass = new MyClass<Metals.Gold>();

我想我可以创建名为Gold,Silver的类来实现这一目标,但我非常喜欢使用枚举来约束我的泛型类的类型。

我在现实世界中想要这样的东西的原因是我正在创建一个事件聚合器(一个发布 - 订阅模型),我希望我的订阅者订阅某种类型的消息T.所以我想它如果我能让我的订阅者使用枚举订阅,那就太好了。

修改 为了澄清,Metals.Gold只是一个例子。我希望客户端库创建自己的枚举\类并改为使用它。我自己并没有定义枚举。

2 个答案:

答案 0 :(得分:6)

无法使用枚举值作为通用参数。在这种情况下你应该使用继承:

public abstract class Metal
{
    protected Metals MetalType { get; private set; }

    protected Metal(Metals metal)
    {
        MetalType = metal;
    }
}

public class Gold : Metal
{
    public Gold() : base(Metals.Gold)
    {
    }
}

更进一步,有关PubSub实施的问题部分过于宽泛,因为应该考虑很多事情。这是一个可以提供一些有用想法的例子:

public class EventHub
{
    // only one receiver per message type is allowed to simplify an example
    private static readonly ConcurrentDictionary<MessageTypes, IReceiver> receivers = 
        new ConcurrentDictionary<MessageTypes, IReceiver>();

    public bool TrySubscribe(MessageTypes messageType, IReceiver receiver)
    {
        return receivers.TryAdd(messageType, receiver);
    }

    public void Publish(IMessage message)
    {
        IReceiver receiver;

        if (receivers.TryGetValue(message.MessageType, out receiver))
        {
            receiver.Receive(message);
        }
    }
}

public interface IMessage
{
    MessageTypes MessageType { get; }
    string Text { get; set; }
}

public interface IReceiver
{
    void Receive(IMessage message);
}

答案 1 :(得分:0)

这不可能是T而不是Type而不是值。

也许我不明白你的问题,但你为什么不这样做呢:

public class MyClass
{
    private readonly Metals _metal;

    public MyClass(Metals metal)
    {
        _metal = metal;
    }

    public void Do()
    {
        //using _metal here
    }
}

var myGoldClass = new MyClass(Metals.Gold);