2016-12-22 82 views
0

我正在處理一個腳本,我可以提供各種對象並告訴它以各種方式修改它們。這對很多類型都非常有效,但我不知道如何去處理List(和其他Collections)。 這不起作用:如何找出對象是否爲任何類型的列表?

List<Transform> transformList = new List<Transform>(); 

void MyFunction(object o) { 
    if(o.GetType() == typeof(int) DoIntStuff(); //Easy 
    else if(o.GetType() == typeof(Color) DoColorStuff(); //Also Easy 
    else if(o.GetType() == typeof(List<>)) DoListStuff(); //Not as easy :(
} 

void Start() { 
    MyFunction(transformList); 
} 

我不能做

typeof(List<T>) 

,因爲T沒有在那裏當然存在。

typeof(List<object>) 

也不起作用。

那麼我怎麼才能知道我所擁有的是什麼類型的列表?

+2

我一直挺直,你在那裏做的不好。爲什麼你需要MyFunction,你不能直接調用DoInt/Color/ListStuff嗎? – Everts

+0

這是一個過於簡單的例子。在實際的腳本中,我可以放入任何GameObject中,並通過Reflection獲取所有組件上的所有字段,然後腳本通過它們進行過濾並根據它在UI中的設置修改值。 – col000r

+0

由於它是一個編輯器腳本,您可能還有一個用於拖動的插槽和一個用於該類型的下拉列表。然後你有一個字典枚舉,行動和基於選定的枚舉類型,它調用該行動。檢查類型的想法可能會導致問題,如果一個類型可以是兩個。假設你最終檢查狗和動物。你的命令也必須考慮。你會遇到很多麻煩。 – Everts

回答

0

假設你要檢查你的類型/從List<T>繼承了一些T(而不是僅僅實現IList<T>一些T),你可以使用下面的擴展方法:

public static class TypeExtensions 
{ 
    public static bool IsGenericList(this Type type) 
    { 
     return type.GetGenericListItemType() != null; 
    } 

    public static Type GetGenericListItemType(this Type type) 
    { 
     while (type != null) 
     { 
      if (type.IsGenericType) 
      { 
       var genType = type.GetGenericTypeDefinition(); 
       if (genType == typeof(List<>)) 
        return type.GetGenericArguments()[0]; 
      } 
      type = type.BaseType; 
     } 
     return null; 
    } 
} 
0

至於我知道,無法從Type對象獲取列表對象的「List」部分。這是因爲根據代碼,不存在「List」類型,但實際上有許多不同的生成類型,它們對應於程序整個過程中「List」接收的每種通用類型。例如,如果你的程序中包含以下內容:

var a = new List<bool>(); 
var b = new List<int>(); 
var c = new List<char>(); 

你編譯的程序將主要包含以下類,每一個在其代碼T與相應型號的電池替換:

List`1 // bool List 
List`2 // int List 
List`3 // char List 

但是,可以欺騙一下。由於通用名稱將始終遵循上面的圖案,您可以使用名稱來執行你的檢查:

var list = new List<int>(); 
var type = list.GetType(); 
bool isList = list.GetType().Name.Split('`')[0] == "List"; 
1

你爲什麼不測試,如果對象實現「IEnumerable的」再檢查內部集合類型(genric集合)像下面這樣:

IEnumerable tempList = o as IEnumerable; 
     if (tempList != null) 
     { 
      IEnumerable<DumyClass> items = tempList.OfType<DumyClass>(); 

      if(items.Count() != 0) 
      { 
       //Then handle the list of the specific type as needed. 
      }    
     } 

如果只有列表類型需要檢查「的IList」這樣的:

IList tempList = o as IList; 

     if (tempList != null) 
     { 
       //Then handle the list as needed. 
     } 

希望這是有益的。

+0

有很多實現IEnumerable的非List類。 – Abion47

+0

感謝您的反饋,我更新了答案。 –

+0

還有很多其他實現'IList'的集合,比如'ArrayList'和'ObservableCollection',更不用提普通的舊數組了。 – Abion47

1

如果你只是要檢查它是否是一個列表我會去與@Ali伊扎特奧德方法,只需要檢查

else if(o is IList) DoListStuff(); 

如果你需要找出含有類型來處理不同的元素列表你可以試試這個擴展方法:

public static class TypeExtensions 
    { 
      /// <summary> 
      /// Gets the inner type of the given type, if it is an Array or has generic arguments. 
      /// Otherwise NULL. 
      /// </summary> 
      public static Type GetInnerListType(this Type source) 
      { 
       Type innerType = null; 

       if (source.IsArray) 
       { 
        innerType = source.GetElementType(); 
       } 
       else if (source.GetGenericArguments().Any()) 
       { 
        innerType = source.GetGenericArguments()[0]; 
       } 

       return innerType; 
      } 
    } 

您可以使用它像

else if(o.GetType().GetInnerListType() == typeof(Transform)) DoTransformListStuff(); 

釷e擴展可以處理各種列表,也可以是數組。在我看來,最好不要只查找List的類型。通過這種方式,如果要進入用戶界面,可以使用替代容器來替換列表,例如使用數組進行性能或使用可觀察集合。它將爲您留下更多未來的設計選擇,並且您可以更好地適應。

相關問題