泛型 – 泛型类型的扩展方法,带有其他泛型类型参数

我想为泛型类型编写扩展方法,以及其他泛型类型参数.我已经有了工作代码,但不喜欢结果,因为用户需要重新输入现有类型的泛型类型参数.

我有一个具体的例子,但请记住,这是一个普遍的问题.我很欣赏有关手头特定问题的反馈,但我正在寻找一般解决方案.

对于Action< T>类型的类,添加一个带有类似于此的签名的扩展方法:

Func<T, TResult> ToFunc<TResult>();

这是我的工作代码:

public static class DelegateExtensions
{
  public static Func<T, TResult> ToFunc<T, TResult>(this Action<T> action)
  {
    return arg => { action(arg); return default(TResult); };
  }
}

但用法很臭:

public void TakesAFunc(Func<int, float> someFunc) { /* ... */ }
// ...
Action<int> someIntAction = /* ... */;
TakesAFunc(someIntAction.ToFunc<int, float>());

在此示例中,int generic参数是唯一可接受的值,因此会导致不必要的代码重复.

类型推断在这里不起作用.我认为这是因为您无法通过返回类型推断出通用参数.

这段代码可以解决问题,但不幸的是似乎不起作用:

public static class DelegateExtensions<T>
{
  public static Func<T, TResult> ToFunc<TResult>(this Action<T> action)
  {
    return arg => { action(arg); return default(TResult); };
  }
}

用法与您期望的完全一样:

public void TakesAFunc(Func<int, float> someFunc) { /* ... */ }
// ...
Action<int> someIntAction = /* ... */;
TakesAFunc(someIntAction.ToFunc<float>());

我注意到System.Linq.Queryable的工作方式与我的第一块代码一样,虽然它通常不需要额外的类型参数,因此类型推断起作用.

是否有任何已知的技巧可以解决这些重复的泛型类型参数?我想到的一个想法是代码生成器或某种类型的宏,但我想不出我是如何干净地做到的.

最佳答案
这类事情的一个常见技巧是传递所需类型的虚拟值,仅用于类型推断,这在涉及匿名类型的某些场景中是必需的.

public static class DelegateExtensions
{
  public static Func<T, TResult> 
  ToFunc<T, TResult>(this Action<T> action, TResult ignored)
  {
    return arg => { action(arg); return default(TResult); };
  }
}

这个技巧有多好取决于个人意见,但每次我打电话都会让我感到困惑,每当我回到一个我称之为的地方时.您还可以更改方法的语义,使第二个参数成为返回值,允许调用者决定是否需要默认值.

至于你的第二个例子,我很确定泛型类型不允许使用扩展方法,但我没有方便的链接

转载注明原文:泛型 – 泛型类型的扩展方法,带有其他泛型类型参数 - 代码日志