【问题标题】:Can I apply attributes to object fields dynamically?我可以动态地将属性应用于对象字段吗?
【发布时间】:2014-10-06 08:36:37
【问题描述】:

我正在开发一个项目,该项目将在 CSV 文件中序列化/存储对象。 (是的,我知道这不是最佳做法,但这是必须的。)

我试图保持我的解决方案干净,所以我在解决方案中有多个项目,其中一个是包含存储/序列化方法的库项目。该项目引用了 CSVhelper,这是我想用来执行 CSV 操作的第 3 方库。

在项目 A 中

foo myobject = new foo(x,y,z);
B.WriteToCsv(myobject);

在项目 B(我的库,引用 csvhelper)中

public static WriteToCsv(foo myobject); // csvhelper would do the work

但是,Csvhelper 需要在我的 foo 对象上设置某些属性才能对其进行操作。

我试图避免在我的 foo 对象类定义文件中应用这些属性,而是更喜欢在项目 B 中动态应用这些属性。

我的问题是,以后是否可以动态应用属性?重点是尽可能保持我的项目干净,但我觉得这会使事情变得更加复杂。这是一个坏主意,还是有针对此问题的通用解决方案?


根据要求更新,例如:

我的 foo 对象定义:

public class Foo
{
    public string a;
    public string b;
    public int c;
}

CsvHelper 需要这样的字段属性:

public class Foo
{
    [CsvColumn(Name = "a", FieldIndex = 1)]
    public string a;
    [CsvColumn(Name = "b", FieldIndex = 2)]
    public string b;
    [CsvColumn(Name = "c", FieldIndex = 3)]
    public int c;
}

为了保持我的代码干净,我想避免在此处添加这些属性,因为我想将所有与存储/序列化相关的代码保留在我的单独库中。 (项目 B)

【问题讨论】:

  • “属性”是指属性,还是 .NET 意义上的属性,例如[Serializable]?如果你能提供一个简短但完整的例子,那真的很有帮助。
  • @JonSkeet 已更新。我的意思是 .NET 意义上的属性,是的。 [XYZ]

标签: .net attributes projects-and-solutions solution code-cleanup


【解决方案1】:

您不能将 [XYZ] 之类的属性附加到现有的编译代码上,它必须在编译时存在。

类库处理此类事情的典型方法是,它可能有一个重载,该重载接收包含元数据的数据结构,另一个重载从属性中提取元数据。如果这个类库中没有这样的重载,那你就不走运了。

如果类允许继承,您可以在运行时生成后代类,在这种情况下,您可以添加您认为合适的任何属性。根据安全模型和现有的类,这可能适合您,也可能不适合您。

【讨论】:

    【解决方案2】:

    是和不是。在你的情况下 - 没有。

    您可以假设动态添加属性,但这需要完全不同的反射方法。请参阅http://msdn.microsoft.com/en-us/library/ms171819.aspx
    我怀疑第三方库是否支持此功能。

    当需要灵活性时,我更愿意将类型/对象与某种配置相关联。
    如果您需要为对象附加一些值,请考虑ConditionalWeakTable

    但不幸的是,所有这些变体都不能用于您的情况。

    如果您需要分离关注点,只需创建具有正确应用属性的 DTO 并使用某种映射器(例如 Automapper)轻松转换实体。

    【讨论】:

      【解决方案3】:

      这种情况的常见模式是“帮助器”实用程序使用属性或解析器或两者的系统。 ProtoBuf 就是一个很好的例子。模式是这样工作的;

      1. 调用者将接口指针传递给 Resolver 方法。
      2. 帮助函数调用解析器对其处理的类型,它可以返回有关如何处理类型的特定信息。
      3. 如果没有传递解析器接口或对解析器的调用未能提供有用的信息,则帮助器将返回到属性以查看它们是否提供了必要的信息。

      这是一个非常简洁的系统,将 SOLID 世界和早期的基于属性的编程风格连接起来。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-29
        • 2018-07-02
        • 2012-01-12
        相关资源
        最近更新 更多