为什么我不能将 String func(SomeEnum) 转换为 Func

发布于 2024-12-12 05:33:38 字数 830 浏览 2 评论 0原文

我认为这与整个方差有关,但我不太明白为什么这是不允许的。

我有一个方法

public void method(Func<Enum, String> func)

我有一些不同的方法,例如

public String doSomething(someEnum)
public String doSomethingElse(someOtherEnum)

我想进行这样的调用

method(doSomething)
method(doSomethingElse)

,但我收到这些错误

从“方法组”转换为System.Func

无法完成此操作的原因是什么?我真的需要将方法重写为这样的多个方法吗?

public void method(Func<someEnum, String> func)
public void method(Func<someOtherEnum, String> func)

那真的很难看。

编辑:

我想在方法中做这样的事情 (注意在我的实际代码中,enumType也是作为Type传入的)

foreach (Enum val in Enum.GetValues(enumType))
{
      func(val);
}

I think this has something to do with the whole variance thing, but I don't quite get why this isn't allowed.

I have a method

public void method(Func<Enum, String> func)

And I have a few different methods such as

public String doSomething(someEnum)
public String doSomethingElse(someOtherEnum)

I want to make calls like this

method(doSomething)
method(doSomethingElse)

but I get these errors

convert from 'method group' to System.Func<System.Enum,string>

What is the reason this cannot be done? Do I really need to rewrite method into multiple methods like this?

public void method(Func<someEnum, String> func)
public void method(Func<someOtherEnum, String> func)

That's really ugly.

edit:

I want to do something like this in the method
(note in my actual code, enumType is also passed in as a Type)

foreach (Enum val in Enum.GetValues(enumType))
{
      func(val);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一梦浮鱼 2024-12-19 05:33:38

你也许可以逃脱

 public void method<TEnum>(Func<TEnum, String> func)

,或者你可以定义一个通用委托:

 delegate String MyFunc<T>(T);

我认为(还没有尝试过)在 C# 4.0 中你可以使用协变/逆变:

 delegate String MyFunc1<in  T>(T);
 delegate String MyFunc2<out T>(T);

这应该意味着你能够分配 MyFunc< ;Derived>MyFunc


Edit 我刚刚发现确实不能使协方差适用于枚举,因为您将无法指定类型约束:

delegate string Display<in T>(T v) where T : Enum;

产量:

 test.cs|5 col 50 错误 702|约束不能是特殊类“System.Enum”

因此,因为您无法从 Enum1 派生 Enum2,所以您只能使用不变的泛型 Enum。混蛋。

you could perhaps get away with

 public void method<TEnum>(Func<TEnum, String> func)

or you can define a generic delegate:

 delegate String MyFunc<T>(T);

I think (haven't tried) in C# 4.0 you can use co-/contravariance with that:

 delegate String MyFunc1<in  T>(T);
 delegate String MyFunc2<out T>(T);

Which should mean that you'd be able to assign MyFunc<Derived> to MyFunc<Base>


Edit I have just found out that indeed covariance cannot be made to work for enums, as you would not be able to specify the type constraint:

delegate string Display<in T>(T v) where T : Enum;

Yields:

 test.cs|5 col 50 error 702| A constraint cannot be special class `System.Enum'

So because you cannot derive Enum2 from Enum1, you're stuck with invariant generic Enums. Bugger.

倾城泪 2024-12-19 05:33:38

您不需要创建重载方法,请考虑:

public void method(Func<Enum, string> func) {...}
public string doSomething(MyEnum e) {...}

method((Enum e) => doSomething((MyEnum)e));

当然,您有责任适当强制/强制转换。

快乐编码。

You do not need to create overloaded methods, consider:

public void method(Func<Enum, string> func) {...}
public string doSomething(MyEnum e) {...}

method((Enum e) => doSomething((MyEnum)e));

Of course it's your responsibility to coerce/cast as appropriate.

Happy coding.

一张白纸 2024-12-19 05:33:38

这里有两个问题:

  1. 您的转换需要协方差,但是Func实际上是第一个泛型参数的逆变。您无法将在特定枚举类型上运行的方法视为可以在任何枚举类型上运行的方法。如果我们尝试使用其他任意枚举类型实例调用委托,您预计会发生什么?

  2. 即使您解决了第一个问题(也许通过反转转换?),这也行不通。变体转换不能与装箱转换很好地配合 - 来自 someEnum -> 的转换。 System.Enum就是这样的一个转换。请参阅:为什么委托逆变不适用于值类型? 了解更多信息。

There's two issues here:

  1. Your conversion is expecting covariance, but Func<in T, out TResult> is actually contravariant on the first generic parameter. You cannot view a method that operates on a specific enumeration type as one that can operate on any enumeration type. What do you expect to happen if we tried to invoke the delegate with some other arbitrary enum-type instance?

  2. Even if you addressed the first issue (perhaps by reversing the conversion?), this wouldn't work. Variant conversions do not play well with boxing conversions - the conversion from someEnum -> System.Enum is such a conversion. See: Why doesn't delegate contravariance work with value types? for more information.

假装爱人 2024-12-19 05:33:38

问题在于 Enum 类实际上并不是您想象的那样。枚举并不是真正派生自 [Enum],也不能将通用约束表示为 Enum。

即,Func;其中 T : Enum 无效。

最好的选择是将其限制为仅接受枚举的方法是:

Method(Funcfunc) where T : struct, IConvertible

The problem is that Enum class isn't really the Enum you think it is. An Enum isn't really derived from [Enum], nor can you express a generic constraint as Enum.

i.e., Func<T> where T : Enum is not valid.

Your best bet is to restrict it to have the method accept only Enums is to have:

Method<T>(Func<T, string> func) where T : struct, IConvertible

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文