C#获取C#中某种对象类型的所有属性

迭戈·阿尔维斯

我有一个具有10个IFormFiles的对象。我想将它们放入IFormFile列表中,以便可以轻松进行操作。

public class Car{

 public IFormFile Imagem1 {get; set;}
 public IFormFile Imagem2 {get; set;}
......

}



 List<IFormFile> imagens = new List<IFormFile>();

foreach(IFormFile imagem in carro.)
  {
          imagens.add(...);
  }

有没有一种方法可以将IFormFile传递给lista,或者我必须操纵在Car对象中使用它们。

我忘了说我是用

images.add(car.Image1);

但是我的代码变得混乱了。因为我必须检查null和许多其他内容。如果我可以循环获得IFormFile,那么我的生活会容易得多。

安德烈

下面的代码演示了如何IFormFile从对象获取type的所有属性car

正如评论中提到的那样,Reflection API相当慢-考虑缓存PropertyInfo对象,或者更好的方法-使用Expressions编译委托,这将遍历对象属性并将其值放入目标集合。

void Main()
{
    var car = new Car();

    var imagens = typeof(Car).GetProperties()
        .Where(x => x.PropertyType == typeof(IFormFile))
        .Select(x => (IFormFile)x.GetValue(car))
        .Where(x => x != null)
        .ToList();
}

PropertyInfo缓存

下面是如何将上面的代码转换为使用缓存PropertyInfo对象的示例

void Main()
{
    var car = new Car();
    var imagens = PropertyGetter<Car, IFormFile>.GetValues(car);
}

public static class PropertyGetter<TObject, TPropertyType>
{
    private static readonly PropertyInfo[] _properties;

    static PropertyGetter()
    {
        _properties = typeof(TObject).GetProperties()
            // "IsAssignableFrom" is used to support derived types too
            .Where(x => typeof(TPropertyType).IsAssignableFrom(x.PropertyType))
            // Check that the property is accessible
            .Where(x => x.GetMethod != null && x.GetMethod.IsPublic && !x.GetMethod.IsStatic)
            .ToArray();
    }

    public static TPropertyType[] GetValues(TObject obj)
    {
        var values = _properties
            .Select(x => (TPropertyType) x.GetValue(obj))
            .ToArray();

        return values;
    }
}

基于表达

另一个示例说明如何实现基于表达式选择特定类型的属性值的逻辑。

public static class PropertyGetterEx<TObject, TPropertyType>
{
    private static readonly Func<TObject, TPropertyType[]> _getterFunc;

    static PropertyGetterEx()
    {
        // The code below constructs the following delegate:
        //
        // o => object.ReferenceEquals(o, null)
        //      ? null
        //      : new TPropertyType[] { o.Prop1, o.Prop2, ... };
        //

        // An expression for the parameter `o`
        var objParam = Expression.Parameter(typeof(TObject), "o");

        // Create expressions for `o.Prop1` ... `o.PropN`
        var propertyAccessExprs = GetPropertyInfos()
            .Select(x => Expression.MakeMemberAccess(objParam, x));

        // Create an expression for `new TPropertyType[] { o.Prop1, o.Prop2, ... }`
        var arrayInitExpr = Expression.NewArrayInit(
            typeof(TPropertyType),
            propertyAccessExprs);

        // Create an expression for `object.ReferenceEquals(o, null)`
        var refEqualsInfo = typeof(object).GetMethod(nameof(object.ReferenceEquals));
        var refEqualsExpr = Expression.Call(
            refEqualsInfo,
            objParam,
            Expression.Constant(null, typeof(TPropertyType)));

        // The condition expression
        var conditionExpr = Expression.Condition(
            refEqualsExpr,
            Expression.Constant(null, typeof(TPropertyType[])),
            arrayInitExpr);

        _getterFunc = Expression
            .Lambda<Func<TObject, TPropertyType[]>>(
                conditionExpr,
                objParam)
            .Compile();
    }

    private static PropertyInfo[] GetPropertyInfos()
    {
        var properties = typeof(TObject).GetProperties()
            // "IsAssignableFrom" is used to support derived types too
            .Where(x => typeof(TPropertyType).IsAssignableFrom(x.PropertyType))
            // Check that the property is accessible
            .Where(x => x.GetMethod != null && x.GetMethod.IsPublic && !x.GetMethod.IsStatic)
            .ToArray();

        return properties;
    }

    public static TPropertyType[] GetValues(TObject obj)
    {
        return _getterFunc(obj);
    }
}

基准结果

以下是上面提供的3种方法的基准测试结果(无缓存,带PropertyInfo缓存,基于表达式)。不出所料,基于表达式的解决方案的性能要比其他解决方案好得多:

|               Method |      Mean |    Error |   StdDev | Rank |
|--------------------- |----------:|---------:|---------:|-----:|
|              NoCache | 789.99 ns | 4.669 ns | 4.139 ns |    3 |
|    PropertyInfoCache | 417.32 ns | 3.271 ns | 3.059 ns |    2 |
| ExpressionBasedCache |  27.55 ns | 0.091 ns | 0.085 ns |    1 |

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在C#中获取对类型中所有类型对象的引用

来自分类Dev

C#反射获取嵌套属性类型中GetValues的对象

来自分类Dev

从 C# 中的类中获取所有属性名称

来自分类Dev

C#从引用的库中获取所有类型

来自分类Dev

从C#中的对象类型获取数据

来自分类Dev

在C#中记录对象的所有属性。如何记录内部对象的属性呢?

来自分类Dev

在C#中记录对象的所有属性。如何记录内部对象的属性呢?

来自分类Dev

如何在C#中获取另一个对象的属性的对象类型?

来自分类Dev

如何在C#中的类中查找某种类型的对象?

来自分类Dev

使用C#中的Selenium获取具有特定类的所有元素的属性值的列表

来自分类Dev

从Parse.com C#(Unity)获取所有对象

来自分类Dev

C#:如何从JS对象获取键的所有值?

来自分类Dev

C#如何从基类的派生类中获取特定类型的所有字段?

来自分类Dev

获取类继承并在C#中实现的所有类型和接口

来自分类Dev

在 C# 中获取一种类型的对象

来自分类Dev

在C#中以字符串形式获取所有属性及其值

来自分类Dev

获取所有数组列表中的属性值c#

来自分类Dev

有什么方法可以对C#中的属性执行某种空合并?

来自分类Dev

如何通过API(C#)从大数组中获取所有对象

来自分类Dev

如何在C#中为通用约束获取有效的类型对象?

来自分类Dev

如何在C#中为通用约束获取有效的类型对象?

来自分类Dev

从C#中的“托管对象”属性获取值的最佳方法

来自分类Dev

C#在BackgroundWorker中BeginInvoke,获取对象属性值

来自分类Dev

C# 获取 T 的属性类型

来自分类Dev

获取多个对象的C#属性值

来自分类Dev

C#中的XMLSerializer不包括类的所有属性

来自分类Dev

在Image API .NET c#中检测所有对象

来自分类Dev

在C#中获取控件的所有事件

来自分类Dev

获取C#中的键值对列表的所有可能组合

Related 相关文章

  1. 1

    在C#中获取对类型中所有类型对象的引用

  2. 2

    C#反射获取嵌套属性类型中GetValues的对象

  3. 3

    从 C# 中的类中获取所有属性名称

  4. 4

    C#从引用的库中获取所有类型

  5. 5

    从C#中的对象类型获取数据

  6. 6

    在C#中记录对象的所有属性。如何记录内部对象的属性呢?

  7. 7

    在C#中记录对象的所有属性。如何记录内部对象的属性呢?

  8. 8

    如何在C#中获取另一个对象的属性的对象类型?

  9. 9

    如何在C#中的类中查找某种类型的对象?

  10. 10

    使用C#中的Selenium获取具有特定类的所有元素的属性值的列表

  11. 11

    从Parse.com C#(Unity)获取所有对象

  12. 12

    C#:如何从JS对象获取键的所有值?

  13. 13

    C#如何从基类的派生类中获取特定类型的所有字段?

  14. 14

    获取类继承并在C#中实现的所有类型和接口

  15. 15

    在 C# 中获取一种类型的对象

  16. 16

    在C#中以字符串形式获取所有属性及其值

  17. 17

    获取所有数组列表中的属性值c#

  18. 18

    有什么方法可以对C#中的属性执行某种空合并?

  19. 19

    如何通过API(C#)从大数组中获取所有对象

  20. 20

    如何在C#中为通用约束获取有效的类型对象?

  21. 21

    如何在C#中为通用约束获取有效的类型对象?

  22. 22

    从C#中的“托管对象”属性获取值的最佳方法

  23. 23

    C#在BackgroundWorker中BeginInvoke,获取对象属性值

  24. 24

    C# 获取 T 的属性类型

  25. 25

    获取多个对象的C#属性值

  26. 26

    C#中的XMLSerializer不包括类的所有属性

  27. 27

    在Image API .NET c#中检测所有对象

  28. 28

    在C#中获取控件的所有事件

  29. 29

    获取C#中的键值对列表的所有可能组合

热门标签

归档