(我很抱歉,如果重复,我不确定是否要检查可空或原始或其他什么)
我正在创建变量Type的对象数组。它可以是int
,string
,Point
或MyCustomClass
(可能没有枚举,但它们与int
相同吗?)。
黑匣子:检查是否构建了 NEEDS 类型。创建数组,如果需要contruction创建每个元素(使用默认值,因为它们此时无关紧要)。构造函数必须是无参数的( - >失败函数),但将字符串视为特殊类型。
输出 object
(运行时类型为int[]
或string[]
或Point[]
等。)
null
的数组。原语和结构很好,我得到int[]
没有问题,但类导致“null[]
”。
public object createArray(Type arrayElementType, int arrayLength)
{
Array a = Array.CreateInstance(arrayElementType, arrayLength);
if (!arrayElementType.IsPrimitive) // correct would be: if (!arrayElementType.IsValueType)
for (int j = 0; j < arrayLength; j++)
a.SetValue(Activator.CreateInstance(arrayElementType), j);
return a;
}
答案 0 :(得分:2)
这里的难点在于创建实例;很容易找出是否将在数组分配上创建实例:只需检查默认(T)值。但是我们如何手动创建实例?如果你的班级有五个构造函数怎么办? 在下面的代码中,我创建了一个实例,如果它的类有一个默认构造函数,它是 public 并且没有参数。
public static T[] CreateArray<T>(int size) {
if (size < 0)
throw new ArgumentOutOfRangeException("size");
T[] result = new T[size];
// You may put any special cases here, e.g. if you want empty strings instead of nulls
// uncomment the exerp:
//if (typeof(T) == typeof(String)) {
// for (int i = 0; i < result.Length; ++i)
// result[i] = (T) ((Object) "");
//
// return result;
//}
// If default value is null, instances should be created
// (if we manage to find out how to do it)
if (Object.ReferenceEquals(null, default(T))) {
// Do we have a constructor by default (public one and without parameters)?
ConstructorInfo ci = typeof(T).GetConstructor(new Type[] { });
// If do, let's create instances
if (!Object.ReferenceEquals(null, ci))
for (int i = 0; i < result.Length; ++i)
result[i] = (T) (ci.Invoke(new Object[] { }));
}
return result;
}
测试用例:
// int is a structore, its default value is 0, so i = [0, 0, 0, 0, 0]
int[] i = CreateArray<int>(5);
// String has no String() constructor, so s[] = [null, null, null, null, null]
String[] s = CreateArray<String>(5);
// Button has Button() constructor, so b[] contains buttons
Button[] b = CreateArray<Button>(5);
答案 1 :(得分:2)
您可以尝试以下代码
public class TypeClass
{
public static T[] CreateArray<T>(int arrayLength) // using T[] would save you from type-casting
where T : new() // <-- Constrain to types with a default constructor
{
T[] t = new T[arrayLength];
for (int j = 0; j < arrayLength; j++)
t[j] = new T();
return t;
}
}
public class MyClass
{
static void Main(string[] args)
{
int [] intArray = TypeClass.CreateArray<int>(5);
string [] stringArray = TypeClass.CreateArray<string>(5);
Point [] pointArray = TypeClass.CreateArray<Point>(5);
MyCustomClass [] myCustomClassArray = TypeClass.CreateArray<MyCustomClass>(5);
}
}
这适用于已定义Primitive
构造函数的所有class
和default
类型。