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.


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]'.



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>




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.



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) { //... }




All Articles