返回适当函数以处理参数化类型参数的通用方法

时间:2013-09-24 22:41:21

标签: c# generics

我基本上想要做的是有一个名为GetHandler<T>的方法,它返回Action<T>。 C#语法允许这样做,但说实话,我不知道你应该如何实现这样的方法。

我想根据T的类型返回不同的函数,所以我当前的尝试看起来像这样:

    public override Action<T> GetHandler<T>()
    {
        if (typeof(T) == typeof(MyType))
        {
            return delegate (T t)
            {
                var msg = (MyType)t;
                //do stuff
            }
        }
        return null;
    }

这不起作用,因为它无法将T转换为MyType。我也无法返回delegate (MyType msg),因为它当然与签名不符。

在这种情况下理想的是,如果C#允许多个泛型方法的覆盖,您可以为单独的输入指定单独的处理程序,然后为处理其他所有内容的catch-all覆盖指定。我仍然不知道我是如何实现所有捕获的。

那么你建议我做些什么来尽可能接近这个功能呢?我看待它的方式,我的函数几乎可以做任何事情,因为T不能被转换成任何有用的东西。

以下是此机制的一个示例用法:

我们有一个类,它有一组实现上述行为的实例。这个类有一个方法SendMessage<T>。该方法考虑了所有包含的实例,并在它们上调用GetHandler<T>(),检查结果是否为null,如果不是,则向处理程序发送消息。

3 个答案:

答案 0 :(得分:3)

不确定您需要什么,因为没有给出太多的背景信息。但你可以摆脱出路:

        return delegate (T t)
        {
            var msg = (MyType)(object)t;
            //do stuff
        }

double-cast会关闭编译器。这通常是要避免的。

答案 1 :(得分:1)

不确定这是否会有所帮助,但您是否考虑过限制通用?

public override Action<T> GetHandler<T>()
    where T : SomeType // Constrain to some type/interface
{
    // You can treat T like SomeType here
}

这样你至少可以将T视为SomeType - 也许这就是你所追求的?如果没有,你能举一个使用范例,这样我就能更好地理解你想要达到的目标吗?

答案 2 :(得分:1)

为什么你不会这样做:

private void HelloMessageHandler(      HelloMessage      msg ) { ... }
private void GoodByeMessageHandler(    GoodByeMessage    msg ) { ... }
private void HowYaDoingMessageHandler( HowYaDoingMessage msg ) { ... }
.
.
.
public Action<T> GetHandler<T>()
{
  Type t = typeof(T) ;
  Delegate handler ;

  if      ( t == typeof(HelloMessage)      ) handler = (Action<HelloMessage>)      HelloMessageHandler      ;
  else if ( t == typeof(GoodByeMessage)    ) handler = (Action<GoodByeMessage>)    GoodByeMessageHandler    ;
  else if ( t == typeof(HowYaDoingMessage) ) handler = (Action<HowYaDoingMessage>) HowYaDoingMessageHandler ;
  else
  {
    string message =  string.Format( "Unknown Message Type specified: {0}" , t.FullName ) ;
    throw new InvalidOperationException(message);
  }

  Action<T> instance = (Action<T>) handler ;
  return instance ;
}

对我来说似乎很简单。