Ответ 1
Затем просто создайте делегат и вызовите его. (не в выражении, конечно, p)
Update:
Как правило, я предпочитаю использовать для этого общие типы, Activator.CreateInstance
просто требует меньше работы. Все зависит от вашей ситуации.
Это то, что я решил с помощью отражения, но хотел бы посмотреть, как это сделать, используя деревья выражений.
У меня есть общая функция:
private void DoSomeThing<T>( param object[] args ) {
// Some work is done here.
}
что мне нужно позвонить из другого места в моем классе. Теперь, как правило, это было бы просто:
DoSomeThing<int>( blah );
но только если я знаю, во время разработки я работаю с int
. Когда я не знаю тип до тех пор, пока время выполнения не понадобится мне. Как я уже сказал, я знаю, как это сделать с помощью отражения, но я хотел бы сделать это через деревья выражений, поскольку мое (очень ограниченное) понимание заключается в том, что я могу это сделать.
Любые предложения или точки на сайтах, где я могу получить это понимание, желательно с образцом кода?
Затем просто создайте делегат и вызовите его. (не в выражении, конечно, p)
Update:
Как правило, я предпочитаю использовать для этого общие типы, Activator.CreateInstance
просто требует меньше работы. Все зависит от вашей ситуации.
Да, это можно сделать с помощью деревьев выражений. Преимущество состоит в том, что вы получаете делегата, поэтому повторные вызовы будут намного быстрее, чем выполнение MethodInfo.Invoke()
снова и снова. Ключевое слово dynamic
может также сделать это.
Пример:
What type would you like to use?
decimal
Selected type 'System.Decimal'
Input Value:
5.47
<<<USING object>>>
The object has static type 'System.Object', dynamic type 'System.Decimal', and value '5.47'
<<<USING dynamic>>>
The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47'
<<<USING reflection>>>
The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47'
<<<USING expression tree>>>
The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47'
код:
using System;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace SO2433436
{
class Program
{
static void LogObject<T>(T t)
{
Console.WriteLine("The object has static type '" + typeof(T).FullName + "', dynamic type '" + t.GetType() + "', and value '" + t.ToString() + "'");
}
static void Main(string[] args)
{
Console.WriteLine("What type would you like to use?");
string typeName = Console.ReadLine();
Type userType;
switch (typeName)
{
case "byte": userType = typeof(byte); break;
case "sbyte": userType = typeof(sbyte); break;
case "ushort": userType = typeof(ushort); break;
case "short": userType = typeof(short); break;
case "uint": userType = typeof(uint); break;
case "int": userType = typeof(int); break;
case "string": userType = typeof(string); break;
case "decimal": userType = typeof(decimal); break;
default:
userType = Type.GetType(typeName);
break;
}
Console.WriteLine("Selected type '" + userType.ToString() + "'");
Console.WriteLine("Input Value:");
string val = Console.ReadLine();
object o = TypeDescriptor.GetConverter(userType).ConvertFrom(val);
Console.WriteLine("<<<USING object>>>");
LogObject(o);
Console.WriteLine("<<<USING dynamic>>>");
LogObject((dynamic)o);
Console.WriteLine("<<<USING reflection>>>");
Action<object> f = LogObject<object>;
MethodInfo logger = f.Method.GetGenericMethodDefinition().MakeGenericMethod(userType);
logger.Invoke(null, new[] { o });
Console.WriteLine("<<<USING expression tree>>>");
var p = new[] { Expression.Parameter(typeof(object)) };
Expression<Action<object>> e =
Expression.Lambda<Action<object>>(
Expression.Call(null,
logger,
Expression.Convert(p[0], userType)
)
, p);
Action<object> a = e.Compile();
a(o);
}
}
}