我可以动态地将属性应用于对象字段吗?

时间:2014-10-06 08:36:38

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

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

我正在尝试保持我的解决方案清洁,因此我在解决方案中有多个项目,其中一个是包含存储/序列化方法的库项目。这个项目引用了CSVhelper,这是我想用来进行CSV操作的第三方库。

在项目A中

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

在项目B(我的lib,引用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)

3 个答案:

答案 0 :(得分:3)

你不能将像[XYZ]这样的属性固定到现有的编译代码上,它必须在编译时出现。

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

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

答案 1 :(得分:1)

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

  1. 调用者传入一个指向Resolver方法的接口指针。
  2. 辅助函数调用解析器处理其类型的处理,它可以返回有关如何处理类型的特定信息。
  3. 如果没有传递Resolver接口或者对Resolver的调用无法提供有用的信息,Helper会回退到属性上以查看它们是否提供了必要的信息。
  4. 这是一个非常简洁的系统,它连接了SOLID世界和早期基于属性的编程风格。

答案 2 :(得分:1)

是和否。在你的情况下 - 否。

您可以假设动态添加属性,但这需要完全不同的反射方法。见http://msdn.microsoft.com/en-us/library/ms171819.aspx
我怀疑第三方图书馆支持这一点。

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

但遗憾的是,所有这些变种都无法用于您的情况。

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