在编译时不知道其 return 类型的情况下调用 Func
Invoke Func without knowing its return type at compile time
我正在尝试写一些东西,但我遇到了死胡同。我有以下代码:
public class ObjectConverter
{
private Dictionary<Type, object> m_Conversions = new Dictionary<Type, object>();
public void AddConversion<TOut>(Func<object, TOut> conversion)
{
m_Conversions[typeof(TOut)] = conversion;
}
public T Convert<T>(object value)
{
var conversion = (Func<object, T>) m_Conversions[typeof(T)];
return conversion(value);
}
}
它是对真实事物的简化,但基本上它允许将对象转换为我们定义了转换的任何类型。
这样你就可以做类似的事情:
// Intialization
converter.AddConversion(x => Convert.ToInt32(x));
// Some other place
converter.Convert<int>("12");
到目前为止一切顺利,但变得复杂的地方是我想像这样编写一个非通用的转换版本
object Convert(object value, Type type)
{
var conversion = m_Conversions[type];
// ???
}
我该怎么做?我想做类似的事情:
object Convert(object value, Type type)
{
var conversion = m_Conversions[type];
var funcType = typeof(Func<,>).MakeGenericType(typeof(object), type);
var invoke = funcType.GetMethod("Invoke");
return invoke.Invoke(conversion, new object[] { value });
}
但是好像效率很低。你能想出更好的方法吗?
Func
is covariant,例如每个 Func<object, string>
都会 return object
所以它可以安全地转换为 Func<object, object>
。所以在你的情况下你根本不需要反思。
public class ObjectConverter
{
private Dictionary<Type, Func<object, object>> m_Conversions = new Dictionary<Type, Func<object, object>>();
public void AddConversion<TOut>(Func<object, TOut> conversion)
{
// need this to support TOut as value type.
m_Conversions[typeof(TOut)] = obj => conversion(obj);
}
public T Convert<T>(object value)
{
return (T) Convert(value, typeof(T));
}
object Convert(object value, Type type)
{
var conversion = m_Conversions[type];
return conversion(value);
}
}
我正在尝试写一些东西,但我遇到了死胡同。我有以下代码:
public class ObjectConverter
{
private Dictionary<Type, object> m_Conversions = new Dictionary<Type, object>();
public void AddConversion<TOut>(Func<object, TOut> conversion)
{
m_Conversions[typeof(TOut)] = conversion;
}
public T Convert<T>(object value)
{
var conversion = (Func<object, T>) m_Conversions[typeof(T)];
return conversion(value);
}
}
它是对真实事物的简化,但基本上它允许将对象转换为我们定义了转换的任何类型。 这样你就可以做类似的事情:
// Intialization
converter.AddConversion(x => Convert.ToInt32(x));
// Some other place
converter.Convert<int>("12");
到目前为止一切顺利,但变得复杂的地方是我想像这样编写一个非通用的转换版本
object Convert(object value, Type type)
{
var conversion = m_Conversions[type];
// ???
}
我该怎么做?我想做类似的事情:
object Convert(object value, Type type)
{
var conversion = m_Conversions[type];
var funcType = typeof(Func<,>).MakeGenericType(typeof(object), type);
var invoke = funcType.GetMethod("Invoke");
return invoke.Invoke(conversion, new object[] { value });
}
但是好像效率很低。你能想出更好的方法吗?
Func
is covariant,例如每个 Func<object, string>
都会 return object
所以它可以安全地转换为 Func<object, object>
。所以在你的情况下你根本不需要反思。
public class ObjectConverter
{
private Dictionary<Type, Func<object, object>> m_Conversions = new Dictionary<Type, Func<object, object>>();
public void AddConversion<TOut>(Func<object, TOut> conversion)
{
// need this to support TOut as value type.
m_Conversions[typeof(TOut)] = obj => conversion(obj);
}
public T Convert<T>(object value)
{
return (T) Convert(value, typeof(T));
}
object Convert(object value, Type type)
{
var conversion = m_Conversions[type];
return conversion(value);
}
}