如何从反射执行显式操作转换? [英] How do I perform explicit operation casting from reflection?
问题描述
我想使用反射,并使用反射进行隐式或显式掩盖.
鉴于我以这种方式定义了Foo
public class Foo
{
public static explicit operator decimal(Foo foo)
{
return foo.Value;
}
public static explicit operator Foo(decimal number)
{
return new Foo(number);
}
public Foo() { }
public Foo(decimal number)
{
Value = number;
}
public decimal Value { get; set; }
public override string ToString()
{
return Value.ToString();
}
}
当我运行这段代码时
decimal someNumber = 42.42m;
var test = (Foo)someNumber;
Console.WriteLine(test); // Writes 42.42 No problems
当我尝试使用Foo作为成员类型定义一个类并使用反射对其进行设置时.我收到以下异常.
Error : Object of type 'System.Decimal' cannot be converted to type 'Foo'.
StackTrace: at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
这是我用来设置反射属性的代码
public class FooComposite
{
public Foo Bar { get; set; }
}
var properties = typeof(FooComposite).GetProperties();
var testFoo = new FooComposite();
foreach(var propertyInfo in properties)
{
propertyInfo.SetValue(testFoo, 17.17m, null); // Exception generated on this line
}
Console.WriteLine(testFoo.Bar); // Never gets here
我该如何进行转换?
与非反射代码的确没有什么不同,您仍然需要将数字显式转换为Foo
:
propertyInfo.SetValue(testFoo,(Foo)17.17m, null);
实时示例: http://rextester.com/rundotnet?code=BPQ74480 >
出于兴趣我尝试了几种选择.
I want to use reflection and do either an implicit or explicit coversion using reflection.
Given I have defined Foo this way
public class Foo
{
public static explicit operator decimal(Foo foo)
{
return foo.Value;
}
public static explicit operator Foo(decimal number)
{
return new Foo(number);
}
public Foo() { }
public Foo(decimal number)
{
Value = number;
}
public decimal Value { get; set; }
public override string ToString()
{
return Value.ToString();
}
}
When I run this code
decimal someNumber = 42.42m;
var test = (Foo)someNumber;
Console.WriteLine(test); // Writes 42.42 No problems
When I try to define a class with Foo as a member type and use reflection to set it. I get the following Exception.
Error : Object of type 'System.Decimal' cannot be converted to type 'Foo'.
StackTrace: at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
Here is the code I use to set the property with reflection
public class FooComposite
{
public Foo Bar { get; set; }
}
var properties = typeof(FooComposite).GetProperties();
var testFoo = new FooComposite();
foreach(var propertyInfo in properties)
{
propertyInfo.SetValue(testFoo, 17.17m, null); // Exception generated on this line
}
Console.WriteLine(testFoo.Bar); // Never gets here
How can I do this conversion?
Well its really no different from your non-reflection code, you still need to explicitly cast the number to a Foo
:
propertyInfo.SetValue(testFoo,(Foo)17.17m, null);
Live example: http://rextester.com/rundotnet?code=BPQ74480
Out of interest I tried a few alternatives.
- Make it an
implicit
cast inFoo
- doesnt work, same error Live - Use
Convert.ChangeType(17.17m,typeof(Foo))
- also doesnt work. Live
这篇关于如何从反射执行显式操作转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!