从C#类中提取非数组/集合的所有字段

时间:2018-04-23 14:20:07

标签: c# reflection

从.NET类中提取单值的任何字段或属性的最佳方法是什么(即不是数组,集合等)

到目前为止我已经

[...]
FieldInfo[] fieldInfos = foo.GetType().GetFields(bindingFlags);
fieldInfos = fieldInfos.Where(f => !f.FieldType.IsArrayOrCollection()).ToArray();
[...]

这是在静态扩展类

public static bool IsArrayOrCollection(this Type testType)
{
    if (testType.IsArray)
        return true;
    if (testType is IEnumerable)
        return true;
    return false;
}

它有效,但我想知道是否有更好的方法?是否会有错过的角落案件?

这个的基本原理是我将单值成员存储在数据库表中作为键值对。显然,这对数组不起作用,因为值是嵌套类型,需要存储在自己的单独表中。

1 个答案:

答案 0 :(得分:0)

您可以使用以下扩展方法:

<div class="gallery-wrapper">
  <div class="actor-images">
    <div class="actor-images fade">
      <div class="image-number">
        1 / 18
      </div>
      <img src="img/frodo.jpg" alt="Elijah Wood - Frodo Baggins">
      <div class="image-caption">
        Elijah Wood - (Frodo Baggins)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        2 / 18
      </div>
      <img src="img/samwise-gamgee-samwise-gamgee.jpg" alt="Sean Astin - Samwise Gamgee">
      <div class="image-caption">
        Sean Astin - (Samwise Gamgee)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        3 / 18
      </div>
      <img src="img/1e53eeea02819531453539bdf3b1d16f.jpg" alt="Dominic Monaghan - Meriadoc 'Merry' Brandybuck">
      <div class="image-caption">
        Dominic Monaghan - (Meriadoc 'Merry' Brandybuck)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        4 / 18
      </div>
      <img src="img/Pippin_Took_profile.jpg" alt="Billy Boyd - Peregrin Took">
      <div class="image-caption">
        Billy Boyd - (Peregrin Took)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        5 / 18
      </div>
      <img src="img/aragorn-lord-of-the-rings.jpg" alt="Viggo Mortensen - Aragorn">
      <div class="image-caption">
        Viggo Mortensen - (Aragorn)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        6 / 18
      </div>
      <img src="img/Orlando-Bloom-as-Legolas-Greenleaf-The-Lord-of-the-Rings-Fellowship-of-the-Ring-Bow.jpg" alt="Orlando Bloom - Legolas Greenleaf">
      <div class="image-caption">
        Orlando Bloom - (Legolas Greenleaf)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        7 / 18
      </div>
      <img src="img/Gimli.jpg" alt="John Rhys-Davies - Gimli">
      <div class="image-caption">
        John Rhys Davis - (Gimli)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        8 / 18
      </div>
      <img src="img/gandalfnod.gif" alt="Sir Ian McKellen - Gandalf the Grey/White">
      <div class="image-caption">
        Sir Ian Mckellen - (Gandalf the Grey/White)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        9 / 18
      </div>
      <img src="img/bilbobaggins.jpg" alt="Ian Holm - Bilbo Baggins">
      <div class="image-caption">
        Ian Holm - (Bilbo Baggins)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        10 / 18
      </div>
      <img src="img/Seanbean_boromir.jpg" alt="Sean Bean - Boromir">
      <div class="image-caption">
        Sean Bean - (Boromir)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        11 / 18
      </div>
      <img src="img/elrond_lotr_090117.jpg" alt="Hugo Weaving - Lord Elrond">
      <div class="image-caption">
        Hugo Weaving - (Lord Elrond)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        12 / 18
      </div>
      <img src="img/theoden.jpg" alt="Bernard Hill - King Theoden">
      <div class="image-caption">
        Bernard Hill - (King Theoden)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        13 / 18
      </div>
      <img src="img/6f4f046b6bbb57dcaf0566897c6f9a1e--arwen-undomiel-liv-tyler.jpg" alt="Liv Tyler - Arwen">
      <div class="image-caption">
        Liv Tyler - (Arwen)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        14 / 18
      </div>
      <img src="img/Eomer_King.jpg" alt="Karl Urban - Eomer">
      <div class="image-caption">
        Karl Urban - (Eomer)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        15 / 18
      </div>
      <img src="img/tumblr_static_eowyn.jpg" alt="Miranda Otto - Eowyn">
      <div class="image-caption">
        Miranda Otto - (Eowyn)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        16 / 18
      </div>
      <img src="img/Faramir.jpg" alt="David Wenham - Faramir">
      <div class="image-caption">
        David Wenham - (Faramir)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        17 / 18
      </div>
      <img src="img/gollum.jpg" alt="Andy Serkis - Gollum/Smeagol">
      <div class="image-caption">
        Andy Serkis - (Gollum/Smeagol) (Motion Capture and Voice)
      </div>
    </div>
    <div class="actor-images fade">
      <div class="image-number">
        18 / 18
      </div>
      <img src="img/saruman.jpg" alt="Christopher Lee - Saruman the White">
      <div class="image-caption">
        Christopher Lee - (Saruman the White)
      </div>
    </div>
  </div>
  <a id="previous-button">&#10094;</a>
  <a id="next-button">&#10095;</a>
</div>
<br>
<div class="dot-span">
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
</div>

那么您可以使用以下方法检索键值对:

public static class Extensions
{
    public static IDictionary<string, object> GetSimpleFieldValues(this object obj)
    {
        return obj.GetType()
            .GetFields(BindingFlags.Instance | BindingFlags.Public)
            .Where(f => f.FieldType.IsSimpleType())
            .ToDictionary(k => k.Name, v => v.GetValue(obj));
    }

    public static bool IsSimpleType(this Type type)
    {
        return type.IsValueType 
            || type.IsPrimitive 
            || new Type[] {
                    typeof(String),
                    typeof(Decimal),
                    typeof(DateTime),
                    typeof(DateTimeOffset),
                    typeof(TimeSpan),
                    typeof(Guid)
                }.Contains(type) 
            || Convert.GetTypeCode(type) != TypeCode.Object;
    }
}

基于this SO回答。

请注意,这将返回用户定义的IDictionary<string, object> values = new YourClass().GetSimpleFieldValues(); 的误报。