2016-06-09 130 views
0

我正在嘗試編寫一個方法,它可以獲取viewModel中的所有ObservableCollections,並將它們轉換爲ObservableCollection<object>。使用反射我已經能夠獲得每個ObservableCollection<T>作爲一個對象,但是我很難將這個對象轉換爲ObservableCollection<object>。這裏是我的代碼到目前爲止:將對象投射爲ObservableCollection <object>

var props = viewModel.GetType().GetProperties(); 

Type t = viewModel.GetType(); 

foreach (var prop in props) 
{ 
    if (prop.PropertyType.Name == "ObservableCollection`1") 
    { 
     Type type = prop.PropertyType; 
     var property = (t.GetProperty(prop.Name)).GetValue(viewModel); 

     // cast property as an ObservableCollection<object> 
    } 
} 

有誰知道我該怎麼做?

+0

投射到'ObservableCollection '不會是類型安全的。你爲什麼想這樣做?也許有另一種方式來實現你的目標。 –

回答

2

將類型名稱與字符串進行比較是一個壞主意。爲了斷言它是一個ObservableCollection,您可以使用以下命令:

可以提取並轉化爲這樣的值:

foreach (var prop in viewModel.GetType().GetProperties()) 
{  
    if (prop.PropertyType.IsGenericType && 
     prop.PropertyType.GetGenericTypeDefinition() == typeof(ObservableCollection<>)) 
    { 
     var values = (IEnumerable)prop.GetValue(viewModel); 

     // cast property as an ObservableCollection<object> 
     var collection = new ObservableCollection<object>(values.OfType<object>()); 
    } 
} 

如果你喜歡它們合併成一個集合,你可以這樣做:

var values = viewModel.GetType().GetProperties() 
    .Where(p => p.PropertyType.IsGenericType) 
    .Where(p => p.PropertyType.GetGenericTypeDefinition() == typeof(ObservableCollection<>)) 
    .Select(p => (IEnumerable)p.GetValue(viewModel)) 
    .SelectMany(e => e.OfType<object>()); 
var collection = new ObservableCollection<object>(values); 
1

回答這個問題是在這裏: https://stackoverflow.com/a/1198760/3179310

但要清楚你的案件:

if (prop.PropertyType.Name == "ObservableCollection`1") 
{ 
    Type type = prop.PropertyType; 
    var property = (t.GetProperty(prop.Name)).GetValue(viewModel); 

    // cast property as an ObservableCollection<object> 
    var col = new ObservalbeCollection<object>(property); 
    // if the example above fails you need to cast the property 
    // from 'object' to an ObservableCollection<T> and then execute the code above 
    // to make it clear: 
    var mecol = new ObservableCollection<object>(); 
    ICollection obscol = (ICollection)property; 
    for(int i = 0; i < obscol.Count; i++) 
    { 
     mecol.Add((object)obscol[i]); 
    }  
    // the example above can throw some exceptions but it should work in most cases 
} 
+0

感謝您的建議。第一種方法產生一個錯誤'不能從'對象'轉換爲'System.Collections.Generic.List '',但第二個工作得很好。 – fyodorfranz

0

你可以使用Cast<T>()擴展方法,但不要忘了,使用這種方法(下)這將創建一個新的實例,所以原始事件不起作用。如果你仍然想接收事件,你應該圍繞它創建一個包裝。

var prop = viewModel.GetType("ObservableCollection`1"); 

var type = prop.PropertyType; 
var propertyValue = (t.GetProperty(prop.Name)).GetValue(viewModel); 

// cast property as an ObservableCollection<object> 
var myCollection = new ObservableCollection<object>(
        ((ICollection)propertyValue).Cast<object>()); 

}