1

(如果重复,我很抱歉,我不确定是否检查可空或原语或其他)

我正在创建变量类型的对象数组。它可以是int, string, Pointor MyCustomClass(虽然可能没有枚举,但它们和int正确的一样?)。


输入:数组元素的类型。

黑盒:检查是否需要构造类型。创建数组,如果需要构造创建每个元素(使用默认值,因为此时它们无关紧要)。构造函数必须是无参数的( -> 失败函数),但将字符串视为特殊类型。

输出:( 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;
}
4

2 回答 2

2

这里的困难在于创建实例;很容易找出是否会在数组分配时创建实例:只需检查default(T)值。但是我们如何手动创建实例呢?如果你的类有五个构造函数怎么办?在下面的代码中,如果它的类有一个默认构造函数,它是公共的并且没有参数,我将创建实例。

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);
于 2013-08-01T07:27:02.410 回答
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);
    }
}

这适用于所有定义了构造函数Primitiveclass类型。default

于 2013-08-01T07:39:42.707 回答