简体   繁体   English

C# 将数组类型的object转换为T,其中T是数组?

[英]C# Convert object of type array to T, where T is an array?

It'd be really good if I could get an object to array conversion working.如果我能让 object 到数组转换正常工作,那就太好了。

Steps:脚步:

  1. We get passed an array from an external source.我们从外部源传递了一个数组。 The array is boxed in an object. Typically the object is an int[] or a double[], but we normally want double[].该数组封装在 object 中。通常 object 是 int[] 或 double[],但我们通常需要 double[]。
  2. Convert it to an array of Type T.将其转换为类型 T 的数组。
  3. return the converted type.返回转换后的类型。

For starters, this works fine对于初学者来说,这很好用

double[] r=Array.ConvertAll<int,double>((int[])o,Convert.ToDouble)

but this doesn't (assume that T is "double") eg double[] R=getValue(o);但这不是(假设 T 是“double”)例如 double[] R=getValue(o);

public T[] getValue<T>(object o){
// ... some logic...
return (T[])Array.ConvertAll<int,double>((int[])o,Convert.ToDouble)

Is there a where constraint that can be used?是否有可以使用的 where 约束? Array is a "Special Object", so we can't use that as a constraint.数组是一个“特殊对象”,所以我们不能将其用作约束。

Is this possible in .net without resorting to IL?这是否可能在 .net 中不诉诸 IL? Is it possilbe if we do resort to IL?如果我们求助于 IL,是否有可能?

thanks, -Steven谢谢,-史蒂文

This worked for me: 这对我有用:

public T[] GetValue<T>(object o)
{
        Converter<int, T> c = new Converter<int, T>(input => (T)System.Convert.ChangeType(input, typeof(T)));
        return (T[])Array.ConvertAll<int, T>((int[])o, c);
}

I hope this helps! 我希望这有帮助!

Try this: 试试这个:

public T[] getValue<T>(object o)
{
    return (T[])Convert.ChangeType(o, typeof(T[]));
}

Use like this: 使用这样:

object doubleArr = new Double[] {1.3, 1.5, 1.7};
var returnedValue = getValue<double>(doubleArr);

Note that if you pass in the wrong type for the template, it will fail at run time 请注意,如果为模板传入了错误的类型,它将在运行时失败

-- Deleted previous content - 删除了之前的内容

Sorry, I did not see the Convert.ToDouble which will of course not compile. 对不起,我没有看到当然不能编译的Convert.ToDouble。 To be able to handle any type of T you have to pass a convert callback to getValue . 为了能够处理任何类型的T,您必须将转换回调传递给getValue

Something like this should do the job: 这样的事情应该做的工作:

public T[] getValue<T>(object o, Converter<int, T> converter)
{
    // ... some logic...
    return (T[])Array.ConvertAll<int,T>((int[])o, converter)
}

Usage: 用法:

double[] result = getValue<double>(o, (i) => Convert.ToDouble(i));

well all three of the above answers work. 以上三个答案都有效。 Awesome. 真棒。 Thanks very much. 非常感谢。

A question: in the notation above Convert.ToDouble in the caller became (i) => Convert.ToDouble(i) . 一个问题:在上面的符号中,调用者中的Convert.ToDouble变为(i) => Convert.ToDouble(i) Is the notation equivilent? 符号是否相等?

I'm new around here... am I supposed to accept an answer somehow? 我是新来的......我应该以某种方式接受答案吗? Not sure if I can because when I posted the question I wasn't registered. 不知道我能否,因为当我发布问题时,我没有注册。

In an extension to the above answers, I got this to work which is very neat solution: 在上述答案的扩展中,我得到了这个非常简洁的解决方案:

public T[,,] getValue_3d<T>(object o) {
    return (T[,,])Convert.ChangeType(o,typeof(T[,,]));
}

usage: 用法:

object doubleArr=new Double[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, 
                                  { { 7, 8, 9 }, { 10, 11, 12 } } };
double[,,] returnedValue=getValue_3d<double>(doubleArr);

One of the things I tried originally was to have T (where T is an n-rank array), get the element type, and then do the conversion. 我最初尝试的一件事就是让T(其中T是一个n级数组),获取元素类型,然后进行转换。 It didn't work too well when it came to returning the value from the function. 从函数返回值时,它不能很好地工作。

To do this even more neatly, it'd be nice if we could do overloads with function return values... but to the best of my knowledge this isn't possible in C# by design. 为了更加整洁地做到这一点,如果我们可以使用函数返回值进行重载,那就太好了......但据我所知,这在C#设计中是不可能的。 Perhaps there's a another trick. 也许还有另外一招。 Also tried TIn + TOut to no avail (TIn is double, and TOut is double[] / double[,] / double[,,] . 也试过TIn + TOut无济于事(TIn是双倍的,TOut是double[] / double[,] / double[,,]

Thanks again. 再次感谢。

Here's yet another solution:D这是另一个解决方案:D

public T[] getValue<T>(object o) => o as T[];

However, this might return a null value because of how as works (instead of crashing --- which might be a good thing?).但是,这可能会返回一个null值,因为它是如何as的(而不是崩溃——这可能是一件好事?)。 as works at runtime, so be careful with how you use it, but if you're using object s then you're already navigating dangerous waters. as在运行时工作,所以要小心你如何使用它,但如果你使用object s 那么你已经在危险的水域中航行了。

I like doing the following so that I don't have to deal with null s everywhere.我喜欢执行以下操作,这样我就不必到处处理null

public T[] getValue<T>(object o) => o as T[] ?? Array.Empty<T>();

Also, this way you don't have to use another level of indirection:3此外,这样你就不必使用另一个间接级别:3


EDIT: I also noticed that you said that编辑:我也注意到你说过

Typically the object is an int[] or a double[], but we normally want double[].通常 object 是一个 int[] 或 double[],但我们通常需要 double[]。

if you know that you only want those two types then you could also be more explicit:如果你知道你只想要这两种类型,那么你也可以更明确:

public T[] getValue<T>(object o) => o switch {
    int[] array    => array as T[],
    double[] array => array as T[],
    var _          => null,
} ?? Array.Empty<T>();

Maybe it's more of a pain to maintain, but it's a bit more explicit.也许维护起来更痛苦,但它更明确一些。 Instead of returning null maybe you could throw and error also to make sure you're not passing the wrong type.除了返回null ,您还可以抛出错误以确保您没有传递错误的类型。

I hope this helps someone:3我希望这对某人有帮助:3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM