I am using Linfu to generate a proxy object for an interface. Everything works fine except when calling a method that returns an IEnumerable<object>
I get an error something like this:
Unable to cast object of type '< IEnumerableRpcCall >d__2' to type 'System.Collections.Generic.IEnumerable`1[System.String]'.
FYI: IEnumerableRpcCall
is the name of the method inside the interceptor code that does yield return object
rather than return object
.
It seems the problem is that linfu is returning a pointer to the method rather than an IEnumerable
. Has anyone found a workaround for this?
The problem seems to be related to casting up from IEnumerable< object >
to IEnumerable< string >
(or whatever type). I solved it by wrapping my enumerator logic inside a custom class that implements IEnumerable<T>
:
public class MyEnumerator<T> : IEnumerable<T>, IEnumerable
{
// custom logic here
}
and then in my interceptor code I use reflection to instantiate the correct generic type as specified in the InvocationInfo object:
private class MyLinfuInterceptor : IInterceptor
{
public object Intercept(InvocationInfo info)
{
MethodInfo methodBeingRequested = info.TargetMethod;
// enumerable return type
if (methodBeingRequested.ReturnType.IsGenericType
&& methodBeingRequested.ReturnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
&& methodBeingRequested.ReturnType.GetGenericArguments().Length == 1)
{
Type constructedEnumerator = typeof(MyEnumerator<>).MakeGenericType(methodBeingRequested.ReturnType.GetGenericArguments());
var result = Activator.CreateInstance(constructedEnumerator);
return result;
}
// code to handle other return types here...
}
}
And now the proxy object for my interface no longer throws an invalid cast exception when I make method calls that return IEnumerable<>