属性与静态属性的区别

3
我有一个需要保存到MongoDB集合中的模型。为了获取集合名称,我有两个选择。
1) 属性
我使用自定义属性装饰类,并使用反射访问其中的值。然后,我可以将其与类型一起缓存,以避免未来的查找。
[MongoCollection("Foo")]
public class Foo
{
}

2) 静态属性

在这里,我有一个包含集合名称的类静态属性。

public class Foo
{
    public static string CollectionName { get { return "Foo"; } } 
}

我发现我倾向于选择前者,因为它看起来更清晰,但这里的一些高级开发人员对反射的使用不以为然。

第一种选项是否有可行性,还是直接选择第二种更好?


4
首先,您的第一个想法是,如果类没有标记属性,那么您将如何过滤它们?在我看来,如果一位资深开发人员对未使用属性表示不屑,那么他可能应该重新思考自己的专业。.NET中的许多机制都基于反射(例如MEF只是其中之一)。几乎所有有用的扩展,比如EntityFramework或NUnit也都是使用反射的。我不建议选择第二个选项。 - lokusking
1
@ChriPf 我觉得这会让重构变得非常困难。如果由于某些原因更改了类名,那么集合也必须被重命名。或者我有什么遗漏吗? - David Pilkington
1
我可以想到另一种选择,使用流畅的符号表示,并有一个单独的映射类来负责MongoDB到POCO的映射。这类似于EF使用代码优先的方式。这样可以完全解耦,并且会导致您的POCO类“Foo”根本没有任何针对MongeDB的映射代码。这将是我的首选。如果不行的话,我会投票支持属性(装饰)。这正是属性存在的原因。 - Igor
@Damien_The_Unbeliever 不,你需要一个要保存的类型的实例。 - David Pilkington
我认为属性方法很好-我猜接受的答案就是这一点。然而,Entity Framework确实使用这种classname == tablename约定(可以更改,但是它是默认值),因此我认为值得一提。 @DavidPilkington - ChriPf
显示剩余6条评论
1个回答

6
这是一种元数据与数据的明显区别:
选项1:属性应该包含与其所附加实体有关的元数据。
选项2:成员字段和属性,无论是实例还是静态,都应该包含组成类的整体值的数据。
因此,选项1,即属性,是表示元数据的正确方法。使用反射只是一种技术细节,可以封装到一个单独的类中,例如AttributeManager,以便轻松访问元数据并适当地缓存它们,以避免性能开销(如果在特定情况下是问题)。

这是我的计划。我有一个内部具有缓存的管理器类。似乎有一种观点认为反射很慢,应该避免使用。即使现有框架使用它,“他们知道如何正确使用它”... - David Pilkington
我可能会继续使用属性,并准备好在代码审查中进行辩论。 - David Pilkington
是的,@DavidPilkington,在需要进行数百万个属性查找的情况下,实际上会变得“缓慢”。在这种情况下,简单的缓存可以消除问题。完全缓存方法的一个可能的优点是能够在运行时“添加”属性。这在某些情况下可能很有用。 - Ondrej Tucny
2
@DavidPilkington 《.NET Framework 设计准则》(https://msdn.microsoft.com/zh-cn/library/2ab31zeh(v=vs.110).aspx)特别指出,如果您担心属性查找的速度,可以考虑**密封**您的自定义属性类。 - rexcfnghk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接