2013-08-01 94 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構造函數定義。

相關問題