检索作为Object传递的HashSet的属性

时间:2014-07-23 10:43:42

标签: c# hashset

我维护一个应用程序的一部分,它将实体框架实体作为对象,并返回其所有属性和相应值的列表。

该方法如下所示:

public static List<string> ExtractAttributes(object data)
{
    List<string> attributes = new List<string>();

    foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(data))
    {
        Console.WriteLine("Name: {0}  Value: {1}  Type: {2}", property.Name, property.GetValue(data), data.GetType());

        attributes.Add(property.Name);
    }
    return attributes;
}

使用以下对象调用此方法:

ExtractAttributes(HashSet<Dog> dogs);

该方法返回Count和Comparer(HashSet的属性)而不是Dog的属性。因此,有必要将data对象转换为hashset集合的第一个对象(它只需要是集合中的第一个对象,原因太长,无法详细解释)。

我写的代码如下:

public static List<String> ExtractAttributes(object data)
{
...
if (data.GetType().IsGenericType &&
    data.GetType().GetGenericTypeDefinition() == typeof(HashSet<>))
{
    List<object> hashSetAsList = new List<object>((IEnumerable<object>)data);
    if (hashSetAsList.Count > 0)
    {
        data = hashSetAsList[0];
    }
}
...
}

考虑到无法改变方法/返回类型中的任何其他内容的约束,有没有办法改进这个丑陋的代码?

修改 ExtractAttributes方法是递归的(以某种方式取决于某些外部XML的逻辑),但可以表示为:

foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(data))
{
    Console.WriteLine("Name: {0}  Value: {1}  Type: {2}", property.Name, property.GetValue(data), data.GetType());

    if (property.GetValue(data).GetType().IsGenericType)
    {
        attributes.AddRange(ExtractAttributes(property.GetValue(data)));
    }
}

3 个答案:

答案 0 :(得分:0)

您可以考虑创建ExtractAttributes方法的重载,例如IEnumerable<object>。这样,当您传递HashSet时,将选择更具体的重载。

答案 1 :(得分:0)

您可以更一般地检查它,尝试将对象转换为简单的非泛型IEnumerable

public static List<String> ExtractAttributes(object data) {
    ...
    if (data is IEnumerable) {
        var enumerator = ((IEnumerable)data).GetEnumerator();
        if (enumerator.MoveNext() && enumerator.Current != null) {
            data = enumerator.Current;
        }
    }
    ...
}

如果你真的只想要为哈希集做这件事,我猜你可以添加你的标准来检查哈希集:

if (data is IEnumerable &&
    data.GetType().IsGenericType &&
    data.GetType().GetGenericTypeDefinition() == typeof(HashSet<>)) {

答案 2 :(得分:-1)

我猜你可以投出HashSet并获取第一个Element

HashSet<object> castedObject = Object as HashSet<object>;

object first = castedObject != null ? castedObject.First() : "";