将函数参数类型转换为对象类型
Cast func parameter type to object type
我有以下功能:
var instance = new MyInstance();
var method = instance.GetType().GetMethod("MyMethod");
Func<bool, PropertyInfo, string, MyClass, object> myFunc = CreateFunc(instance, method);
private static Func<bool, PropertyInfo, string, MyClass, object> CreateFunc(
object instance,
MethodInfo method)
{
var propertyHandlerInterface = instance.GetType().GetInterface(typeof(IPropertyHandler<>).Name);
var valueType = propertyHandlerInterface.GetGenericArguments().First();
var funcType = typeof(Func<,,,,>);
var type = funcType.MakeGenericType(
valueType,
typeof(PropertyInfo),
typeof(string),
typeof(MyClass),
typeof(object));
return (Func<bool, PropertyInfo, string, MyClass, object>)Delegate.CreateDelegate(
type,
instance,
method);
}
我可以这样称呼它:
var myValue = true;
var result = myFunc(myValue, somePropertyInfo, "some string", someMyClassInstance);
我需要能够将第一个参数 bool
转换为 object
以便函数看起来像这样...
Func<object, PropertyInfo, string, MyClass, object> myFunc = CreateMyFunc();
...所以我可以这样称呼它:
object myValue = true; // <-- This is key, myValue is of type object.
var result = myFunc(myValue, somePropertyInfo, "some string", someMyClassInstance);
我该如何实现?
澄清一下:我希望我的 CreateFunc
具有以下签名:
private static Func<object, PropertyInfo, string, MyClass, object> CreateFunc(
object instance,
MethodInfo method)
而不是
private static Func<bool, PropertyInfo, string, MyClass, object> CreateFunc(
object instance,
MethodInfo method)
但我不知道如何将我的委托转换为该类型。
例如,给定一个 Func<bool, object>
实例,而您想要一个 Func<object, object>
实例,最简单的方法是将它包装在 lambda 中并转换传递给它的参数:
Func<bool, object> func1 = ...;
Func<object, object> func2 = o => func1((bool)o);
当然要记住,这样做已经消除了 C# 编译器在使用委托时通常会提供的类型安全。调用者可以调用 func2
并传递一个 而不是 的参数 bool
值,在这种情况下会抛出 InvalidCastException
。
如果您不能保证使用您以这种方式创建的委托的调用者将始终传递一个 bool
值作为 object
参数,那么您需要包括包装委托中的一些回退机制,例如检查 o
参数值的类型,如果它不是 bool
,则将默认值传递给 func1
委托,或者简单地 return 一些默认值 return 值而不是调用 func1
委托。
例如:
Func<object, object> func2 = o => o is bool f ? func1(f) : null;
我有一个建议(如何更改“对象”的类型)。我希望这就是您正在寻找的“提示”。
System.Convert.ChangeType(sourceObject, typeof(TargetType));
我有以下功能:
var instance = new MyInstance();
var method = instance.GetType().GetMethod("MyMethod");
Func<bool, PropertyInfo, string, MyClass, object> myFunc = CreateFunc(instance, method);
private static Func<bool, PropertyInfo, string, MyClass, object> CreateFunc(
object instance,
MethodInfo method)
{
var propertyHandlerInterface = instance.GetType().GetInterface(typeof(IPropertyHandler<>).Name);
var valueType = propertyHandlerInterface.GetGenericArguments().First();
var funcType = typeof(Func<,,,,>);
var type = funcType.MakeGenericType(
valueType,
typeof(PropertyInfo),
typeof(string),
typeof(MyClass),
typeof(object));
return (Func<bool, PropertyInfo, string, MyClass, object>)Delegate.CreateDelegate(
type,
instance,
method);
}
我可以这样称呼它:
var myValue = true;
var result = myFunc(myValue, somePropertyInfo, "some string", someMyClassInstance);
我需要能够将第一个参数 bool
转换为 object
以便函数看起来像这样...
Func<object, PropertyInfo, string, MyClass, object> myFunc = CreateMyFunc();
...所以我可以这样称呼它:
object myValue = true; // <-- This is key, myValue is of type object.
var result = myFunc(myValue, somePropertyInfo, "some string", someMyClassInstance);
我该如何实现?
澄清一下:我希望我的 CreateFunc
具有以下签名:
private static Func<object, PropertyInfo, string, MyClass, object> CreateFunc(
object instance,
MethodInfo method)
而不是
private static Func<bool, PropertyInfo, string, MyClass, object> CreateFunc(
object instance,
MethodInfo method)
但我不知道如何将我的委托转换为该类型。
例如,给定一个 Func<bool, object>
实例,而您想要一个 Func<object, object>
实例,最简单的方法是将它包装在 lambda 中并转换传递给它的参数:
Func<bool, object> func1 = ...;
Func<object, object> func2 = o => func1((bool)o);
当然要记住,这样做已经消除了 C# 编译器在使用委托时通常会提供的类型安全。调用者可以调用 func2
并传递一个 而不是 的参数 bool
值,在这种情况下会抛出 InvalidCastException
。
如果您不能保证使用您以这种方式创建的委托的调用者将始终传递一个 bool
值作为 object
参数,那么您需要包括包装委托中的一些回退机制,例如检查 o
参数值的类型,如果它不是 bool
,则将默认值传递给 func1
委托,或者简单地 return 一些默认值 return 值而不是调用 func1
委托。
例如:
Func<object, object> func2 = o => o is bool f ? func1(f) : null;
我有一个建议(如何更改“对象”的类型)。我希望这就是您正在寻找的“提示”。
System.Convert.ChangeType(sourceObject, typeof(TargetType));