将对象转换为ObservableCollection <object>

时间:2016-06-09 18:59:08

标签: c# .net observablecollection

我正在尝试编写一个方法来获取viewModel中的所有ObservableCollections,并将每个ObjectableCollections转换为ObservableCollection<object>。使用反射我已经能够将每个ObservableCollection<T>作为对象,但是我很难将此对象转换为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>
    }
}

有谁知道我该怎么办?

3 个答案:

答案 0 :(得分:2)

将类型名称与字符串进行比较是个坏主意。为了断言它是ObservableCollection,您可以使用以下内容:

if (prop.PropertyType.IsGenericType && 
    prop.PropertyType.GetGenericTypeDefinition() == typeof(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 :(得分: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
}

答案 2 :(得分: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>());

}