【问题标题】:Defining a delegate blueprint定义委托蓝图
【发布时间】:2016-02-15 06:57:50
【问题描述】:

我正在阅读this 有人回答的问题建议这种方法:

public static void Method<T>(Func<int,T> del) {
  var t = del(42);
}

应该这样使用:Method&lt;SomeType&gt;(x =&gt; new SomeType(x));
Method 正文对这个问题并不重要。 如果委托/lambda 不是那种“风格”,则该方法将无法按预期工作。例如,如果它被称为Method(x =&gt; new Foo());,它将无法“工作”,因为解决方法的目的将丢失。
目的是确保T 有一个构造函数,它采用int 类型的1 个参数。我希望我能做到T(int) 那么无论如何要确保代表应该始终是x =&gt; new SomeType(x)?或者有其他选择吗?我查了很多地方,也想不出什么。

【问题讨论】:

  • 您可以为接收任意数量的预期参数的方法创建重载。
  • 是的,我可以让Method 接受 T 和 int 但它将如何创建FooFoo 对该方法未知。假设Method 在另一个库中。
  • 不,我的意思是创建另一个Method(Func&lt;int&gt; del) 会使另一个过载,这样你就可以用任何一个调用它。因为它是你不能让现有的接受Func&lt;int&gt;,因为它需要Func&lt;int, T&gt;
  • 没有。我想要的是del 应该采用x =&gt; new Foo(x) 的形式,这样我就可以确保Foo 有一个构造函数采用int 类型的参数,因为没有这样的通用约束。
  • 我认为您可能需要扩展您所询问的内容,从您的问题来看,您似乎希望能够使用两种不同类型的 lambda 调用 Method,但是从 cmets 看来也许您想将其限制为仅接受某种类型,对吗?唯一的方法是为每种预期类型创建一个重载,即为每种类型创建一个重载Method(Func&lt;int, int&gt; del) 和`Method(Func del) 等。您不能创建通用约束列表或约束到特定类型。

标签: c# delegates


【解决方案1】:

您不需要 func 来执行此操作。只需传入您想要的类型,它将返回对象并确保将 int 传递给它。然后,您基本上只是创建了一个工厂方法,该方法将通过传入的整数为您提供所需的类型。

public T Method<T>(int whatever) where T : class
{
     return (T)Activator.CreateInstance(typeof(T), whatever);
}

var type = Method<SomeType>(55);

【讨论】:

  • 这是不可能的。你不能用参数调用T()。这会产生编译器错误“'T': cannot provide arguments when creating an instance of a variable type”
  • 这再次违反了我链接的问题中解决方法的目的。如果我这样做,我如何确保T 将有一个构造函数采用 int?如果不是这个Method 会抛出某种运行时异常。当然,我在编码时可以小心,但我想使用泛型来执行规则。
  • 好的,我明白你现在想要做什么。没有办法确保 T 有一个采用 int 的构造函数,而不使用反射首先检查它,或者像我的示例中那样创建一个新的并尝试调用它。在任何一种情况下,如果您传入的类型不采用构造函数参数,即使在您想要的 func 中完成,也可能出现异常。不过这是个好问题。
  • 谢谢。然后,如果构造函数没有采用 int,我将只使用反射并抛出异常。 :)
猜你喜欢
  • 2023-03-08
  • 2016-08-25
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多