2016-06-09 126 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>()); 

}