为什么我不能将 String func(SomeEnum) 转换为 Func?
我认为这与整个方差有关,但我不太明白为什么这是不允许的。
我有一个方法
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你也许可以逃脱
,或者你可以定义一个通用委托:
我认为(还没有尝试过)在 C# 4.0 中你可以使用协变/逆变:
这应该意味着你能够分配
MyFunc< ;Derived>
到MyFunc
Edit 我刚刚发现确实不能使协方差适用于枚举,因为您将无法指定类型约束:
产量:
因此,因为您无法从 Enum1 派生 Enum2,所以您只能使用不变的泛型
Enum
。混蛋。you could perhaps get away with
or you can define a generic delegate:
I think (haven't tried) in C# 4.0 you can use co-/contravariance with that:
Which should mean that you'd be able to assign
MyFunc<Derived>
toMyFunc<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:
Yields:
So because you cannot derive Enum2 from Enum1, you're stuck with invariant generic
Enum
s. Bugger.您不需要创建重载方法,请考虑:
当然,您有责任适当强制/强制转换。
快乐编码。
You do not need to create overloaded methods, consider:
Of course it's your responsibility to coerce/cast as appropriate.
Happy coding.
这里有两个问题:
您的转换需要协方差,但是
Func
实际上是第一个泛型参数的逆变。您无法将在特定枚举类型上运行的方法视为可以在任何枚举类型上运行的方法。如果我们尝试使用其他任意枚举类型实例调用委托,您预计会发生什么?即使您解决了第一个问题(也许通过反转转换?),这也行不通。变体转换不能与装箱转换很好地配合 - 来自
someEnum -> 的转换。 System.Enum
就是这样的一个转换。请参阅:为什么委托逆变不适用于值类型? 了解更多信息。There's two issues here:
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?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.问题在于 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