我有一个函数可以生成包含不同数据的对象(该函数根据类型用随机数据填充对象)。该函数返回一个 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/