我有一个函数可以生成包含不同数据的对象(该函数根据类型用随机数据填充对象)。该函数返回一个 object[] 因为该类型仅在运行时知道(并且它作为参数传递给该函数)。

double[] values;

values = factory.GetData(typeof(double), 10);

不幸的是,我收到一个编译器错误:



如何以编程方式转换 object[]

编辑:

这是原始函数:
    public object[] GetData(Type type, int howMany)
    {
        var data = new List<object>();

        for (var i = 0; i < howMany; i++)
        {
            data.Add(Convert.ChangeType(GetRandom(type), type));
        }

        return data.ToArray();
    }

其中 GetRandom() 创建一个 type 类型的对象并为其分配一个随机值(随机整数、随机字符串、随机 double 、仅基本类型)

这是 GetRandom() 函数:
   public T GetRandom<T>()
    {
        var type = typeof(T);

        if (type == typeof(int))
        {
            return prng.Next(0, int.MaxValue);
        }

        if (type == typeof(double))
        {
            return prng.NextDouble();
        }

        if (type == typeof(string))
        {
            return GetString(MinStringLength, MaxStringLength);
        }

        if (type == typeof(DateTime))
        {
            var tmp = StartTime;
            StartTime += new TimeSpan(Interval * TimeSpan.TicksPerMillisecond);
            return tmp;
        }
    }

最佳答案

现在所有的答案(大部分)实际上都回答了这个问题,没有人真正谈论使用泛型。现在这可能不适合您的直接账单,但可以很容易地添加以解决问题,并且不需要调用应用程序了解如何理解返回值。

这很简单。只需定义一个接受泛型类型的重载(注意 T )

public T[] GetData<T>(int count)
{
    Type tType = typeof(T);
    //.. TODO: Generate our array.. anyway you wish..
    List<T> list = new List<T>();
    for (int i = 0; i < count; i++)
        list.Add(Activator.CreateInstance<T>());
    return list.ToArray();
}

所以这是一个基本示例,可以通过以下方式调用:
Factory factory = new Factory();
var arr = factory.GetData<double>(10); //returns a typed array of double

现在,从调用者的角度来看,我们知道我们正在接收的数据类型为 double 或它们提供的类型。

这是您最初问题的替代方案。但是,如果您的对象数组并不总是最初请求的类型,那么这将不起作用。

编辑

定义数组实际上取决于您如何定义对象,但让我们采用您的初始概念并将其调整为上述相同:
public T[] GetData<T>(int count)
{
    Type tType = typeof(T);
    //.. TODO: Generate our array.. anyway you wish..
    List<T> list = new List<T>();
    for (int i = 0; i < count; i++)
        list.Add((T)GetRandom(tType));
    return list.ToArray();
}

在新示例中,我们假设 Method GetRandom() 将返回请求的类型。请求的类型是基于 typereference (typeparam) T 的通用类型。我们可以通过调用 typeof(T) 来获取实际类型。现在在这个例子中,我们简单地直接转换 GetRandom() 对象响应(我假设 GetRandom() 返回一种 object 类型。

最终编辑

如评论中所述,您可以将 object GetRandom(Type type) 更改为 T GetRandom<T>() 。这将允许您为您的随机生成特定类型。我建议阅读泛型 https://msdn.microsoft.com/en-us/library/512aeb7t.aspx

现在,一件不太明显的事情是,您如何命名您的泛型取决于您。您不必使用 T 并且您可以在一个方法调用中使用多个泛型,就像您可能已经使用的许多方法一样。

** 最终最终编辑 **

只是为了详细说明如何将 GetRandom 方法更改为泛型,我们仍然必须使用 object 类型,它实际上是唯一允许对任何类型进行直接装箱转换的类型。您可以使用 as 关键字,但这可能会导致其他问题。现在 GetRandom(Type type) 方法返回该类型的随机对象。如前所述,这仅限于几种类型,所以让我们举一个例子。

首先要了解的是如何处理我们的各种类型。现在我个人喜欢定义一个接口(interface)。因此,让我们为所有要继承的随机类型定义一个接口(interface)。如下:
interface IRandomTypeBuilder
{
    object GetNext();
}

作为使用 GetNext() 方法返回随机类型实体的简单接口(interface)。这将返回基于泛型参数 T 的类型化响应。

现在这个接口(interface)的一些简单实现。
class DoubleRandomBuilder : IRandomTypeBuilder
{
    static Random rng = new Random();
    public object GetNext()
    {
        return rng.NextDouble() * rng.Next(0, 1000);
    }
}

class IntRandomBuilder : IRandomTypeBuilder
{
    static Random rng = new Random();
    public object GetNext()
    {
        return rng.Next(int.MinValue, int.MaxValue);
    }
}

class StringRandomBuilder : IRandomTypeBuilder
{
    static Random rng = new Random();
    static string aplha = "abcdefghijklmnopqrstuvwxyz";
    public object GetNext()
    {
        string next = "";
        for (int i = rng.Next(4, 10), j = i + rng.Next(1, 10); i < j; i++)
            next += aplha[rng.Next(0, aplha.Length)];
        return next;
    }
}

class BoolRandomBuilder : IRandomTypeBuilder
{
    static Random rng = new Random();
    public object GetNext()
    {
        return rng.Next(0, 2) % 2 == 0;
    }
}

是的,这些非常简单,但我们有 4 种不同的类型,它们都定义了 GetNext() 方法并返回该类型的随机值。现在我们可以定义 GetRandom<T>() 方法。
public T GetRandom<T>()
{
    Type tType = typeof(T);
    IRandomTypeBuilder typeGenerator = null;
    if (tType == typeof(double))
        typeGenerator = new DoubleRandomBuilder();
    else if (tType == typeof(int))
        typeGenerator = new IntRandomBuilder();
    else if (tType == typeof(string))
        typeGenerator = new StringRandomBuilder();
    else if (tType == typeof(bool))
        typeGenerator = new BoolRandomBuilder();
    return (T)(typeGenerator == null ? default(T) : typeGenerator.GetNext());
}

关于c# - 在 C# 上从 object[] 转换为 double[],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31834399/

10-10 19:50