Why can't I use String func (SomeEnum) for Func <Enum, String>?
I think this has something to do with the whole mistake, but I donβt quite understand why this is not allowed.
I have a method
public void method(Func<Enum, String> func)
And I have several different methods, such as
public String doSomething(someEnum) public String doSomethingElse(someOtherEnum)
I want to make such calls
method(doSomething) method(doSomethingElse)
but i get these errors
convert from 'method group' to
System.Func<System.Enum,string>
What is the reason for this cannot be done? Do I really need to rewrite a method to several methods like this?
public void method(Func<someEnum, String> func) public void method(Func<someOtherEnum, String> func)
This is really ugly.
edit:
I want to do something like this in a method (note that in my actual code, enumType is also passed as a Type)
foreach (Enum val in Enum.GetValues(enumType)) { func(val); }
you could leave with
public void method<TEnum>(Func<TEnum, String> func)
or you can define a common delegate:
delegate String MyFunc<T>(T);
I think (have not tried) in C # 4.0 you can use co- / contravariance with this:
delegate String MyFunc1<in T>(T); delegate String MyFunc2<out T>(T);
This should mean that you could assign MyFunc<Derived>
to MyFunc<Base>
Edit I just found out that covariance cannot be used for enumerations, since you cannot specify a type constraint:
delegate string Display<in T>(T v) where T : Enum;
Productivity:
test.cs|5 col 50 error 702| A constraint cannot be special class `System.Enum'
Since you cannot get Enum2 from Enum1, you are stuck with the invariant generic Enum
s. Asshole.
There are two questions here:
Your transformation expects covariance, but
Func<in T, out TResult>
is actually contravariant in the first generic parameter. You cannot view a method that works with a specific type of enumeration, like one that can work with any type of enumeration. What do you expect if you try to call a delegate with some other instance of the enum instance?Even if you turned to the first question (perhaps by converting the conversion?), This will not work. Conversions of options do not go very well with conversions to boxing - the conversion from
someEnum -> System.Enum
is such a conversion. See Why is it not necessary to delegate contravariance work with type values? for more information.
The problem is that the Enum class is not really the Enum you are thinking about. Enum is not actually derived from [Enum], and you cannot express a general restriction as Enum.
ie, Func<T> where T : Enum
not valid.
It is best to limit it to the fact that the method only accepts Enums to have:
Method<T>(Func<T, string> func) where T : struct, IConvertible