Casting System.Func <T>

I am redistributing code that uses the following construct. What I would like to do is make it generic so that I can have other types of parameters in Func.

IDictionary<string, Func<Employee, string>>

      

I tried using:

IDictionary<string, Func<Object, string>>

      

Then return it:

(IDictionary<string, Func<Object, string>>)myDictionary

      

But I am getting an exception saying that I cannot use

Unable to pass object of type 'System.Collections.Generic.Dictionary 2[System.String,System.Func

2 ...

I have been playing with generics, but it seems to me that I still cannot set and generic field in my class

private IDictionary<string, Func<T, string>> lineSpecification;

      

Looped around so any pointers would be appreciated.

EDIT:

This is the complete error message I am getting:

System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Func`2[DataObjects.Employee,System.String]]' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.

      

+3


source to share


3 answers


It won't be type safe.



If that were legal, what would happen if you passed Car

one of the casted values ​​(which really is Func<Employee, string>

)?

+5


source


Instead, enter the dictionary like IDictionary<string, object>

and enter the resulting value:

IDictionary<string, object> myDictionary = new Dictionary<string, object>();
var myDelegate = (Func<Employee, string>)myDictionary["my employee delegate"];

      



Of course, this will fail if you try to use the wrong Func type, so you need to be sure to know which keys map to Func types.

+2


source


It sounds like you want your dictionary to have different types of values; in other words, that one dictionary can contain Func<Employee, string>

and Func<Customer, string>

.

If so, then you basically have no choice but to use a common base type for the type argument TValue

and discard delegates when you retrieve them from the dictionary. The general base type can be System.Delegate

or System.Object

.

(There are actually other options besides this, but they just push casting to a different part of the design. For example, you could write a wrapper class that handles casting for you. Such solutions usually don't apply, don't settle for a cost-benefit analysis.)

My dictionary will only store the same type, but in different scenarios I want it to be able to store different types. The problem I am having is casting from Func to Func throws a casting exception.

In this case, it is not clear why you want to have Dictionary<string, Func<Object, string>>

and not Dictionary<string, Func<Employee, string>>

. If any given dictionary will only contain one delegate type, then create the dictionary accordingly:

Dictionary<string, Func<Employee, string>> dict = new Dictionary<string, Func<Employee, string>>();

      

If the dictionary is a member of a generic class or a local variable or parameter of a generic method, you can use type parameters in the dictionary declaration:

class Processor<T>
{
     void Process(T value, Dictionary<string, Func<T, string>> functions) { //... }
}

      

0


source







All Articles