【问题标题】:Attempt to convert object[] to ValueType[] at runtime尝试在运行时将 object[] 转换为 ValueType[]
【发布时间】:2012-04-21 11:38:52
【问题描述】:

当值类型仅在运行时已知时,是否可以将 object[] 转换为诸如 double[] 之类的值类型?如果无法使用 .net 内置转换将 object[] 中的对象转换为值元素类型(例如 double),则完全可以接受异常。

var original = new object[] { 1 , 2 , 3 , 4 , 5 , 6 }
Type resultType = typeof( double[] ); // or any means of getting a type at runtime
var result = ??

以下尝试失败:

# error: Object must impliment IConvertible
Convert.ChangeType( original , resultType );

# error: Object cannot be stored in an array of this type.
var result = Array.CreateInstance( resultType , original.Length );
for ( int i = 0 ; i < original.Length ; i++ )
{
    result.SetValue( Convert.ChangeType( original[ i ] , resultType.GetElementType() ) , i );
}

【问题讨论】:

  • 真的,为什么不直接创建一个双精度数组并将每个对象封装成双倍并将其设置到它的索引中呢?简单的for循环?可以添加“if (obj is double){...}”来处理错误的对象数组。
  • resultType 不保证为双精度。它在运行时确定。它可以是任何值类型。
  • 为什么不使用通用的 Cast 扩展方法?如果您想限制 ValueTypes,您可以创建自己的 Cast 方法,该方法使用扩展 Cast 方法,但如果“!typeof(T).IsValueType”则抛出。看看我的回答。
  • 你能展示一个完整的工作示例吗?我认为很难使用在运行时确定类型的泛型函数。见stackoverflow.com/questions/326285/…stackoverflow.com/questions/234008/…

标签: c# .net .net-4.0


【解决方案1】:

您的最后一次尝试非常接近:第一行应该是

var result = Array.CreateInstance(resultType.GetElementType(), original.Length);

因为Array.CreateInstance元素类型 作为它的第一个参数。除此之外,它应该可以完美运行。

【讨论】:

    【解决方案2】:
    private T[] Cast<T>(params object[] items)
    {
        if (!typeof(T).IsValueType)
        {
            throw new ArgumentException("Destined type must be Value Type");
        }
    
        return items.Cast<T>().ToArray();
    }
    

    【讨论】:

    • 赞成取消反对票。尽管 OP 对此不是很清楚,但他在代码 cmets 中说 type object 可能仅在运行时可用。
    猜你喜欢
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    • 2014-02-14
    相关资源
    最近更新 更多