如何定义具有泛型返回类型的静态函数,意味着覆盖

时间:2017-02-06 02:01:31

标签: c# generics interface

我正在努力做一些令人费解的事情,这会伤害我的大脑。所以,如果你能想到一个比我要求的更好的方式,那么我全都听见了!

基本上我有一个类ClientSession,这个类通过tcp接受消息并通过OnMessageReceived事件公开它们。我试图告诉ClientSession解析消息,然后使用MessageParser类在事件中公开它,作为通用参数传递。我想使用静态方法来避免实例化对象。我还希望其他任何人能够创建他们自己的消息解析器,它会吐出他们想要的任何Type

基本上,我需要

  • 保证ClientSession类可以在实例化时传递它的泛型类型TryParse()
  • 实施TryParse()作为静态方法

喜欢这个

public static abstract class MessageParser<TMessage>
{
    public static abstract TMessage TryParse(byte[] bytes);
}

然后其他人可以定义自己的解析器:

public static class ProtoParser : MessageParser<ProtoMessage>
{
    public static ProtoMessage TryParse(byte[] bytes)
    {
        do some stuff...
        return new ProtoMessage;
    }
}

最后:

public class ClientSession<TParser>
{
    public void OnMessageReceived(Object sender, MessageEventArgs e)
    {
        return TParser.TryParse(e.bytes);
    }
{

我知道静态和抽象是不可能的,但你明白了。

我有一种直觉,我只是接近这个错误。提前谢谢!

1 个答案:

答案 0 :(得分:1)

请参阅here了解您当前方法无法正常工作的原因。

一些替代方案:

传递解析器的实例

public abstract class MessageParser<TMessage>
{
    public abstract TMessage TryParse(byte[] bytes);
}

public class ProtoParser : MessageParser<ProtoMessage>
{
    public override ProtoMessage TryParse(byte[] bytes)
    {
        return null;
    }
}

public class ClientSession<TParser, TMessage> where TParser : MessageParser<TMessage>
{
    TParser _parser;
    public ClientSession(TParser parser)
    {
        _parser = parser;
    }

    public TMessage OnMessageReceived(Object sender, MessageEventArgs e)
    {
        return _parser.TryParse(e.bytes);
    }
}

使用它:

var cs = new ClientSession<ProtoParser, ProtoMessage>(new ProtoParser());

使用在ClientSession

中创建的解析器实例
public abstract class MessageParser<TMessage>
{
    public abstract TMessage TryParse(byte[] bytes);
}

public class ProtoParser : MessageParser<ProtoMessage>
{
    public override ProtoMessage TryParse(byte[] bytes)
    {
        return null;
    }
}

public class ClientSession<TParser, TMessage> where TParser : MessageParser<TMessage>, new()
{
    TParser _parser = new TParser();

    public TMessage OnMessageReceived(Object sender, MessageEventArgs e)
    {
        return _parser.TryParse(e.bytes);
    }
}

使用它:

var cs = new ClientSession<ProtoParser, ProtoMessage>();

将方法传递给ClientSession

public static class ProtoParser
{
    public static ProtoMessage TryParse(byte[] bytes)
    {
        return null;
    }
}

public class ClientSession<TMessage>
{
    Func<byte[], TMessage> _parser;
    public ClientSession(Func<byte[], TMessage> parser)
    {
        _parser = parser;
    }

    public TMessage OnMessageReceived(Object sender, MessageEventArgs e)
    {
        return _parser(e.bytes);
    }
}

然后使用它:

var cs = new ClientSession<ProtoMessage>(ProtoParser.TryParse);