Array.SetValue 在运行时的 C# 类型转换

标签 c# arrays reflection casting runtime

我正在尝试使用反射创建一个数组,并将值插入其中。我正在尝试为许多不同的类型执行此操作,因此希望 createAndFillArray 函数能够做到这一点:

String propertyName1 = "prop1";
String propertyName2 = "prop2";

Type t1 = typeof(myType).getProperty(propertyName1).PropertyType.getElementType();
Type t2 = typeof(myType).getProperty(propertyName2).PropertyType.getElementType();

double exampleA = 22.5;
int exampleB = 43;

Array arrA = createAndFillArray(t1, exampleA);
Array arrB = createAndFillArray(t2, exampleB);

private Array createAndFillArray(Type t, object val){
    Array arr = Array.CreateInstance( t, 1); //length 1 in this example only, real-world is of variable length.
    arr.SetValue( val, 0 ); //this causes the following error: "System.InvalidCastException : Object cannot be stored in an array of this type."
    return arr;
}

A类如下:

public class A{
    public A(){}

    private double val;
    public double Value{
        get{ return val; }
        set{ this.val = value; }
    }

    public static implicit operator A(double d){
        A a = new A();
        a.Value = d;
        return a;
    }
}

和 B 类非常相似,但是 int:

public class B{
    public B(){}

    private double val;
    public double Value{
        get{ return val; }
        set{ this.val = value; }
    }

    public static implicit operator B(double d){
        B b = new B();
        b.Value = d;
        return b;
    }
}

myType 类似于以下内容:

public class myType{
    public A prop1{ get; set; }
    public B prop2{ get; set; }
}

我希望隐式运算符能够确保将 double 转换为 A 类,或将 int 转换为 B 类,从而避免错误;但这显然不是这样。

上面是在自定义反序列化类中使用的,它从自定义数据格式中获取数据并填充相应的.Net对象属性。我是通过反射和在运行时这样做的,所以我认为两者都是不可避免的。我的目标是 C# 2.0 框架。

我有几十个(如果不是数百个)类似于 AB 的类,所以我更愿意找到一个改进了 createAndFillArray< 的解决方案 方法而不是改变这些类的解决方案。

最佳答案

这是 an example使用反射找到转换方法。因此,如果您可以在您的类型上获取该方法并自行进行转换。

复制自:http://bytes.com/topic/c-sharp/answers/903775-getting-operators-using-reflection

//EndType is the type I want to PRODUCE
//StartType is the type I am pulling data FROM
MethodInfo mi = EndType.GetMethod(
    "op_Implicit", 
    (BindingFlags.Public | BindingFlags.Static), 
    null, 
    new Type[] { StartType }, 
    new ParameterModifier[0]
);
//Now if mi is NOT null, it means there is an operator that allows for converting StartType to EndType, if it is null, there isn't one

关于Array.SetValue 在运行时的 C# 类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4572212/

相关文章:

c# - 如何遍历一个程序的所有子元素

php - 检查字符串是否包含垃圾邮件单词

c - 在C中交换两行二维字符数组

scala - 如何获得 ClassTag 的类?

c# - 将不可序列化的类转换为字节数组

c# - XNA 初始化和 LoadContent 之间的差异

javascript - 查找数组中的数字是否介于两个数字之间并输出介于两者之间的值的数量

向上转换之前的java反射字段类型

java - 如何通过 Java 中的反射来转换泛型基类型?

c# - 带有 'New...' 项的数据绑定(bind) WPF ComboBox