2013-08-01 95 views
1

(对不起,如果重复的,我不知道,如果要检查可为空或原语或其他)C# - 如何检查是否需要构造类型的对象?

我创建一个变量类型的对象的数组。它可以是intstringPointMyCustomClass(大概没有虽然枚举,但他们一样int吧?)。


输入:类型数组元素。

黑匣子:检查是否需要构建类型需要。创建数组,如果需要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; 
} 
+1

这真的不清楚你想达到的目标。让我们以'string'为例 - 你显然需要一个非空字符串引用的数组,但是这些字符串的内容应该是什么? –

+0

@JonSkeet内容无关紧要。他们不能是空的。 – Bitterblue

+0

你能介绍一些关于这方面的代码吗? – Naren

回答

2

这里的难点是在creationing实例;它很容易找出是否实例将在数组分配创建:只检查默认(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); 
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构造函数定义。

相关问题