var is not detecting result of method with dynamic input - c#

I have the following problem
private int GetInt(dynamic a)
{
return 1;
}
private void UsingVar()
{
dynamic a = 5;
var x = GetInt(a);
}
But x is still dynamic.
I don't understand why.

Since your argument a in the GetInt method call have the type dynamic, so the overload resolution occurs at run time instead of at compile time.
Based on this:
Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type dynamic, or if the receiver of the method call is of type dynamic.
Actually by using the dynamic you are using the late binding (defers to later), and it means, the compiler can't verify it because it won't use any static type analysis anymore.
The solution would be using a cast like this:
var x = (int)GetInt(a);
The following is how the compiler is treating your code:
private void UsingVar()
{
object arg = 5;
if (<>o__2.<>p__0 == null)
{
Type typeFromHandle = typeof(C);
CSharpArgumentInfo[] array = new CSharpArgumentInfo[2];
array[0] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null);
array[1] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
<>o__2.<>p__0 = CallSite<Func<CallSite, C, object, object>>
.Create(Microsoft.CSharp.RuntimeBinder.Binder
.InvokeMember(CSharpBinderFlags.InvokeSimpleName, "GetInt", null, typeFromHandle, array));
}
object obj = <>o__2.<>p__0.Target(<>o__2.<>p__0, this, arg);
}

Related

How to check method exists in C# with certain particular signature?

I want to check if the method for certain parameters is implemented. In this scenario, I have for example these method overloads:
public class Transformations
{
public string TransformFrom(string s) { return s;}
public string TransformFrom(int i) { return "00" + i.ToString();}
public string TransformFrom(DateTime dt) { return
DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff");}
}
Suppose I have decimal like:
object obj = 1M;
If I now call TransformFrom(obj), I get an exception.
Other part of my program returns unfortunately only objects, which really are concrete types like int or datetime. And I want to transform some of these objects to string so that those can be written to the log. So this is a runtime problem. Also I want that my Transformations-class is general enough to be used in other programs too, so there can be objects of any type.
Is there fast way to find out that this method overload does not exist?
Either way you are currently going to get a compile time error, even if there was an overload that accepted a decimal. You can approach this one of 2 ways depending on your needs:
To resolve this at compile time you have to cast to the correct type.
object obj = 1;
var objAsInt = (int) obj;
var result = transformationInstance.TransformFrom(objAsInt);
If there is no proper overload you will get a compile time error and you can resolve this at design time.
To resolve this at runtime use reflection to figure out if there is an overload of the type and if there is pass the instance.
object obj = 1;
var underlyingType = obj.GetType();
var method = typeof(Transformations).GetMethod("TransformFrom", new Type[] { underlyingType });
if(method != null)
{
var result = method.Invoke(transformationInstance, new []{obj});
}
It is possible to find out whether a given overload exists using reflection:
public static bool HasOverloadForArgument(Type targetType, string methodName, object arg)
{
var methodInfo = targetType.GetMethod(name: methodName, types: new[] { arg.GetType() });
return methodInfo != null;
}
Live sample
I'm not sure what is the whole idea here as there won't be much you can do when the transformation is not available during runtime.
Maybe, you'd just be best off using dynamic to avoid all the reflection stuff and caching required otherwise, e.g.
var boxedInt = (object)1;
var boxedFloat = (object)1f;
dynamic dynamicInt = boxedInt;
dynamic dynamicFloat = boxedFloat;
var intResult = new Transformations().TransformFrom(dynamicInt); // works
var floatResult = new Transformations().TransformFrom(dynamicFloat); // throws binder exception

Cannot convert from `Expression<Func<T1, T2>>` to `Expression<Func<object, object>>`

UPDATE: This question was marked as duplicated, but although I understand the issue with the code, I don't have a solution. Is it possible for the code to work by only changing the method bodies and not the method signatures?
I'm tying to wrap my head around Expression and Func, while trying to build a class like the following:
public class Test<TBase>
{
private IList<Expression<Func<object, object>>> _expressions = new List<Expression<Func<object, object>>>();
public void AddExpression<T>(Expression<Func<TBase, T>> e)
{
_expressions.Add(e);
}
public void AddExpression<T1, T2>(Expression<Func<T1, T2>> e)
{
_expressions.Add(e);
}
}
I need/would like to keep a list of expressions, where the types inside the Func may vary. I though the code above would work but it doesn't. It fails with:
Cannot convert from 'Expression<Func<TBase, T>>' to 'Expression<Func<object, object>>'
Cannot convert from 'Expression<Func<T1, T2>>' to 'Expression<Func<object, object>>'
Resharper says:
Argument type 'Expression<Func<TBase, T>>' is not assignable to parameter type 'Expression<Func<object, object>>'
Argument type 'Expression<Func<T1, T2>>' is not assignable to parameter type 'Expression<Func<object, object>>'
Is it possible for the code to work by only changing the method bodies and not the method signatures?
UPDATE: This question was marked as duplicated, but although I understand the issue with the code, I don't have a solution. Is it possible for the code to work by only changing the method bodies and not the method signatures?
Yes, you can keep the method signatures, but you'll have to rewrite the expressions...
Like this:
public void AddExpression<T1, T2>(Expression<Func<T1, T2>> e)
{
var originalParameter = e.Parameters[0];
// object par1
var parameter = Expression.Parameter(typeof(object), originalParameter.Name);
// T1 var1
var variable = Expression.Variable(typeof(T1), "var1");
// (T1)par1
var cast1 = Expression.Convert(parameter, typeof(T1));
// var1 = (T1)par1;
var assign1 = Expression.Assign(variable, cast1);
// The original body of the expression, with originalParameter replaced with var1
var body = new SimpleParameterReplacer(originalParameter, variable).Visit(e.Body);
// (object)body (a cast to object, necessary in the case T2 is a value type. If it is a reference type it isn't necessary)
var cast2 = Expression.Convert(body, typeof(object));
// T1 var2; var1 = (T1)par1; (object)body;
// (the return statement is implicit)
var block = Expression.Block(new[] { variable }, assign1, cast2);
var e2 = Expression.Lambda<Func<object, object>>(block, parameter);
_expressions.Add(e2);
}
I'm using the SimpleParameterReplacer from another response I gave some time ago.
In the end a (T1 x) => x.Something (with x.Something being a T2) is transformed in:
(object x) =>
{
var var1 = (T1)x;
return (object)var1.Something;
}

converting a dictionary with unknown value types to json

I wrote the code below to convert a dictionary to a json string.
The catch here is that the dictionary values could be of various types
string, int, string[], int[], float[], ...
I tried using generics, but I get a compile error where I do GetParamList because it expects me to specify the actual type.
I was wondering if there is a way that I can avoid putting lots of if/else conditions to achieve what I want.
private static string GetParamList<T>(object values)
{
if (values.GetType().Equals(typeof(string[])) )
{
string[] res = (string[])values;
if (values.GetType().Equals(typeof(string[])))
{
for (int i = 0; i < res.Length; i++)
{
if (!res[i].ToString().StartsWith("\""))
{
res[i] = string.Format("\"{0}\"", res[i]);
}
}
}
return string.Join(",", res);
}
else if (values.GetType().Equals(typeof(string)))
{
return string.Format("\"{0}\"", values);
}
else// array of numbers:
{
string[] res = ((T[])values).Select(x => x.ToString()).ToArray<string>();
return string.Join(",", res);
}
}
private static string dictToJson(Dictionary<string, object> data)
{
List<string> entries = new List<string>();
foreach (var entry in data)
{
Type T = entry.Value.GetType();
entries.Add(string.Format("\"{0}\": {1}", entry.Key, GetParamList<T>(entry.Value)));
}
return "{" + string.Join(",", entries.ToArray<string>()) + "}";
}
The mistake is made here:
Type T = entry.Value.GetType();
What you're doing here is not getting a generic parameter - instead, you're getting the object of class Type which represents the parameter you want. Generics are designed to work with a type known at compile time, so that the JIT Compiler can create the definition of the class on the fly for you. You thus cannot pass in the Type object as a generic parameter.
There are, however, several ways to get around this.
The first and easiest is to have a factory method which can perform generic inference, and pass the generic parameter as dynamic. This will force the CLR to hold off until runtime to decide what type to use, and then use the best matched type for the parameters. Not that this will not work with your code as is - generic inferencing demands you use T as the type of a parameter in addition to the generic type, such as:
private static string GetParamList<T>(T[] values)
The second would be to metacode the operation and compile the call using the System.Linq.Expressions namespace, which could be significantly more verbose:
var val = Expression.Constant(entry.Value);
var method = typeof(MyType) // Where MyType is the type containing "GetParamList"
.GetMethod("GetParamList")
.MakeGenericMethod(t); // Where t is the desired type
string result = Expression
// Lambda turns an expression tree into an expressiong tree with an explicit delegate signature
.Lambda<Func<String>>(
Expression.Call(null, method, val)) // "Call the method against nothing (it's static) and pass in val (which is a constant in this case)"
.Compile() // This compiles our expression tree
.Invoke(); // Run the method
You are doing it the hard way, try this.
public List<Event_Log> GetAll()
{
List<Event_Log> result = new List<Event_Log>();
//add result collection here...
return result;
}
Thanks for recommending "Newtonsoft.Json".
I used that package this way and all the problems are solved:
private static string dictToJson(Dictionary<string, object> data)
{
string json = JsonConvert.SerializeObject(data, Formatting.None, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
});
return json;
}

Passing a value using Expression Trees does not work

I am working on a function that takes a delegate type and a delegate of type Action<Object[]> and creates a dynamic function of the given type, that passes, if called, all arguments to the given action handle:
public static T GetEventDelegate<T>(Action<Object[]> handler) where T : class
{
if (!typeof(T).IsSubclassOf(typeof(Delegate)))
throw new Exception("T must be a delegate type");
Type[] argTypes = typeof(T).GetMethod("Invoke").GetParameters().Select((para) => para.ParameterType).ToArray();
List<ParameterExpression> lstArgs = new List<ParameterExpression>(
argTypes.Select((arg)=>Expression.Parameter(arg))
);
ParameterExpression result = Expression.Variable(typeof(Object[]));
var assignExpression = Expression.NewArrayInit(typeof(Object),lstArgs.ToArray());
var callExpression = Expression.Call(handler.Method, result);
var block = Expression.Block(
new List<ParameterExpression>(){result},
new Expression[]{assignExpression,callExpression}
);
var del = Expression.Lambda(block, lstArgs.ToArray()).Compile();
return Delegate.CreateDelegate(typeof(T), del, "Invoke") as T;
}
private static void testDel()
{
var del = GetEventDelegate<EventHandler>(
(x) =>
{
//Error, because x == null
Debug.Print(x.ToString());
}
);
del("testString", new EventArgs());
}
Unfortunately the action handler only gets a null value passed (see testDel()).
Could you please help me to find the error?
Thanks in advance!
Your problem is because you initialize the result ParameterExpression as type Object, but never actually assign it a value. What this pretty much compiles down to (after calling compile) is:
void Func(arguments..)
{
Object result;
new object[](arguments...);
method(result);
}
You never actually assign the array to the result with an assign expression.
Unrelated to your problem, you could use Expression.Lambda() when creating the lambda because you have the type from the generic.

Speeding up Reflection Invoke C#/.NET

There are plenty of posts on speeding up reflection invokes, examples here:
Speeding up Reflection API with delegate in .NET/C#
https://codeblog.jonskeet.uk/2008/08/09/making-reflection-fly-and-exploring-delegates/
and here:
Example : Speeding up Reflection API with delegate in .NET/C#
My question is about speeding up generic invokes. Is this possible at all?
I've got an abstract class and a class which implements it...
public abstract class EncasulatedMessageHandler<T> where T : Message
{
public abstract void HandleMessage(T message);
}
public class Handler : EncasulatedMessageHandler<MyMessageType>
{
public int blat = 0;
public override void HandleMessage(MyMessageType message) { blat++; }
}
What I want to do is build up a list of these message handler classes and quickly invoke their HandleMessage()
At the moment, I'm doing something that's approximately this:
object handler = Activator.CreateInstance(typeof(Handler)); // Ignore this, this is done up front.
MethodInfo method = type.GetMethod("HandleMessage", BindingFlags.Instance | BindingFlags.Public);
Action<object> hook = new Action<object>(delegate(object message)
{
method.Invoke(handler, new object[] { message });
});
// Then when I want to invoke it:
hook(new MyMessageType());
That's not the whole thing, but it's the important stuff...
The method.Invoke is very slow, I'd like to keep the generic parameters on the class, I realise I could lock this down to object and cast it in the HandleMessage method, but I'm trying to avoid doing this.
Is there anything I can do to speed this up? It's currently orders of magnitude slower than direct calls.
Any help would be appreciated.
Are you using C# 4? If so, dynamic may speed things up:
Action<object> hook = message => ((dynamic)handler).HandleMessage((dynamic)message);
Using Delegate.CreateDelegate() should be a lot faster. You will end up with a pointer to the real function, not a delegate that calls Invoke().
Try this:
object handler = Activator.CreateInstance(typeof(Handler));
var handlerType = handler.GetType();
var method = handlerType.GetMethod("HandleMessage", BindingFlags.Instance | BindingFlags.Public);
var paramType = handlerType.GetGenericArguments()[0];
// invoke the MakeHandleMessageDelegate method dynamically with paramType as the type parameter
// NB we're only doing this once
Action<object> hook = (Action<object>) this.GetType().GetMethod("MakeHandleMessageDelegate")
.MakeGenericMethod(paramType)
.Invoke(null, new [] { handler });
In the same class add the following generic method. We invoke this dynamically above because we don't know the type parameter at compile time.
public static Action<object> MakeHandleMessageDelegate<T>(object target)
{
var d = (Action<T>)Delegate.CreateDelegate(typeof(Action<T>), target, "HandleMessage");
// wrap the delegate another that simply casts the object parameter to the required type
return param => d((T)param);
}
You then have a delegate that casts the parameter to the required type, then calls the HandleMessage method.
You can use Delegate::CreateDelegate. This is significantly faster than Invoke().
var handler = Activator.CreateInstance(typeof(Handler));
var method = type.GetMethod("HandleMessage", BindingFlags.Instance | BindingFlags.Public);
var hook = (Action<object>)Delegate.CreateDelegate(typeof(Action<object>), handler, method);
// Then when you want to invoke it:
hook(new MyMessageType());
Feel free to benchmark it, but I have benched it before and it was significantly faster.
Edit: I see your problem now, you can't do it the way I suggested.
You can use Expressions to compile a delegate that does the invoke for you, this will be very fast:
var type = typeof(Handler);
var instance = Activator.CreateInstance(type);
var method = type.GetMethod("HandleMessage", BindingFlags.Instance | BindingFlags.Public);
var originalType = type;
// Loop until we hit the type we want.
while (!(type.IsGenericType) || type.GetGenericTypeDefinition() != typeof(EncasulatedMessageHandler<>))
{
type = type.BaseType;
if(type == null)
throw new ArgumentOutOfRangeException("type");
}
var messageType = type.GetGenericArguments()[0]; // MyMessageType
// Use expression to create a method we can.
var instExpr = Expression.Parameter(typeof(object), "instance");
var paramExpr = Expression.Parameter(typeof(Message), "message");
// (Handler)instance;
var instCastExpr = Expression.Convert(instExpr, originalType);
// (MyMessageType)message
var castExpr = Expression.Convert(paramExpr, messageType);
// ((Handler)inst).HandleMessage((MyMessageType)message)
var invokeExpr = Expression.Call(instCastExpr, method, castExpr);
// if(message is MyMessageType) ((Handler)inst).HandleMessage((MyMessageType)message);
var ifExpr = Expression.IfThen(Expression.TypeIs(paramExpr, messageType), invokeExpr);
// (inst, message) = { if(message is MyMessageType) ((Handler)inst).HandleMessage((MyMessageType)message); }
var lambda = Expression.Lambda<Action<object, Message>>(ifExpr, instExpr, paramExpr);
var compiled = lambda.Compile();
Action<Message> hook = x => compiled(instance, x);
hook(new MyMessageType());
Edit: Apart from my Expression example above, the following will also work - and is what I do in these types of scenarios.
var instance = (IEncapsulatedMessageHandler)Activator.CreateInstance(typeof(Handler));
instance.HandleMessage(new MyMessageType());
public class Message { }
public class MyMessageType : Message { }
public interface IEncapsulatedMessageHandler
{
void HandleMessage(Message message);
}
public abstract class EncasulatedMessageHandler<T> : IEncapsulatedMessageHandler where T : Message
{
public abstract void HandleMessage(T message);
void IEncapsulatedMessageHandler.HandleMessage(Message message)
{
var msg = message as T;
if (msg != null)
HandleMessage(msg);
}
}
public class Handler : EncasulatedMessageHandler<MyMessageType>
{
public override void HandleMessage(MyMessageType message)
{
Console.WriteLine("Yo!");
}
}
If you know the signature, use Delegate.CreateDelegate.
If you don't know the signature, it's very tricky to get something that's fast. If you need speed, then whatever you do, try to avoid Delegate.DynamicInvoke which is extremely slow.
(Note that "slow" is very relative here. Make sure you really need to optimize this. DynamicInvoke is something like 2.5 million invocations per second (on my machine), which is very likely fast enough. The implementation below is more like 110+ million invocations per second and is faster than Method.Invoke.)
I found an article that discusses a way to do it (invoke a method fast without knowing the signature at compile time). Here is my version of the implementation. The weird issue is that you could build a lambda which represents the invocation, but you would not know the signature of that lambda and would have to call it dynamically (slowly). But instead, you can bake the strongly typed invocation into the lambda, with the lambda representing the act of invocation rather than the specific method itself. (The lambda ends up being a Func<object, object[], object> where you pass an object and some values and get back the return value.)
public static Func<object, object[], object> ToFastLambdaInvocationWithCache(
this MethodInfo pMethodInfo
) {
Func<object, object[], object> cached;
if (sLambdaExpressionsByMethodInfoCache.TryGetValue(pMethodInfo, out cached))
return cached;
var instanceParameterExpression = Expression.Parameter(typeof(object), "instance");
var argumentsParameterExpression = Expression.Parameter(typeof(object[]), "args");
var index = 0;
var argumentExtractionExpressions =
pMethodInfo
.GetParameters()
.Select(parameter =>
Expression.Convert(
Expression.ArrayAccess(
argumentsParameterExpression,
Expression.Constant(index++)
),
parameter.ParameterType
)
).ToList();
var callExpression = pMethodInfo.IsStatic
? Expression.Call(pMethodInfo, argumentExtractionExpressions)
: Expression.Call(
Expression.Convert(
instanceParameterExpression,
pMethodInfo.DeclaringType
),
pMethodInfo,
argumentExtractionExpressions
);
var endLabel = Expression.Label(typeof(object));
var finalExpression = pMethodInfo.ReturnType == typeof(void)
? (Expression)Expression.Block(
callExpression,
Expression.Return(endLabel, Expression.Constant(null)),
Expression.Label(endLabel, Expression.Constant(null))
)
: Expression.Convert(callExpression, typeof(object));
var lambdaExpression = Expression.Lambda<Func<object, object[], object>>(
finalExpression,
instanceParameterExpression,
argumentsParameterExpression
);
var compiledLambda = lambdaExpression.Compile();
sLambdaExpressionsByMethodInfoCache.AddOrReplace(pMethodInfo, compiledLambda);
return compiledLambda;
}
No, that is (sadly) not possible. Reflection is slow and MethodInfo.Invoke() is no exception. Couldn't you use (generic) Interfaces and thus direct calls?
Edit update: One thing comes to mind to really speed this up, but the coding overhead is massive: You can use dynamic code generation and compilation. That would mean dynamically building the source code that would call the method without reflection, dynamically compiling and executing this. This would mean an initially performance impact for creating and compiling the classes that do your work, but then you have direct calls for every subsequent calls.

Categories

Resources