2016-06-21 68 views
-1

我正在使用“奇怪值”来区分选项列表的第三方控件。他们使用两种不同的属性来唯一标识每个选项。使用静态只读与静态获取器模仿常量

Example: 
"Field" + "RW" = "CheckedOutBy" 
"System" + "N" = "Name" 
"Field + "N" = "Notifier" 

总共有37个不同的选择(每个组合这两个值组成37个独特选项)。

我已经创建了一个存储这两个值的结构,并且我将为每个选项创建一个新的结构实例。

public struct ColumnCode : IEquatable<ColumnCode> 
{ 
    public static readonly ColumnCode Empty = new ColumnCode(); 

    private readonly ColumnType _columnType; 
    private readonly string _code; 

    internal ColumnCode(ColumnType columnType, string code) 
    { 
     _columnType = columnType; 
     _code = code; 
    } 

    public override string ToString() { ... } 
    public bool Equals(ColumnCode other) { ... } 
    public override int GetHashCode() { ... } 
} 

理想我想创建为每个选项的“常数”,但由于常量不是我想尝试和模仿恒定的选项。

我提出的两种方法是使用静态只读字段或静态属性只有一个getter。

public static class FieldOption 
{ 
    public static ColumnCode CheckedOutBy { get; } = new ColumnCode(ColumnType.Field, "XW"); 
    public static ColumnCode Name { get; } = new ColumnCode(ColumnType.System, "N"); 
    public static ColumnCode Notifier { get; } = new ColumnCode(ColumnType.Field, "N"); 
} 

public static class FieldOption 
{ 
    public static readonly ColumnCode CheckedOutBy = new ColumnCode(ColumnType.Field, "XW"); 
    public static readonly ColumnCode Name= new ColumnCode(ColumnType.System, "N"); 
    public static readonly ColumnCode Notifier = new ColumnCode(ColumnType.Field, "N"); 
} 

在任何情况下,现在可以参考我在我的C#代码的选择使用FieldOption.CheckedOutByFieldOption.NameFieldOption.Notifier等,但我不知道,如果一个方法是优于其他。

其中一个选择比另一个更好地模仿const,还是有更好的方法,我不考虑。

我已经阅读了大量的互联网信息,我仍然没有提出一个很好的答案。它似乎有些冲突。许多信息状态偏好属性而不是字段,但在本文中(https://msdn.microsoft.com/en-us/library/ms229057(v=vs.110).aspx)Microsoft说“DO使用公共静态只读字段用于预定义的对象实例”,所以我觉得静态只读字段是正确的选择。

我也不确定这里的反射如何影响比赛。我想确保FieldOptions的值不能改变,即使通过反射。

任何帮助,将不胜感激。

+0

你知道关键字的作用吗? –

+0

@Jeroen Vannevel不知道我理解你的问题?我只是想知道如果C#编译器处理这些不同?是否有性能优势等 –

+0

一个是静态的,另一个不是。一个是财产,另一个是领域。显然,这些将会有所不同 - 决定你感兴趣的差异取决于你。如果你的意思是*所有*差异,那么最好的做法是阅读文档,看看静态效应是什么'和一个领域和财产如何不同。一旦你制定了更具体的问题,我们可以回答,而不是 –

回答

1

我想,以确保为FieldOptions的值不能改变,甚至通过反射

来完成,这将是使用只读属性的唯一方法,而且当时只有你每次吸气剂被调用时,如重新实例相应的值:

public static ColumnCode CheckedOutBy 
{ 
    get { return new ColumnCode(ColumnType.Field, "RW"); } 
} 

使用语法,你已经证明,或与私用二传手自动性能,还有一个支持字段,并且支持字段尚可通过改变反射,尽管稍微有些困难,因为字段名在源代码中不可见并且具有依赖于编译器实现的名称。

当然,每次调用getter时重新实现这个值都会带来负面的性能影响。因此,将该财产设置为只读(即免于反射)是有成本的。在你的情况下,这种性能成本是否重要是你自己必须确定的。对这个问题没有“一个正确的答案”。

我已经在互联网上阅读了大量的信息,我还没有提出一个很好的答案。其中一些似乎是冲突

这是因为,除了你有一些特定的约束,通知你的决定(如想防止反射能够改变价值)的情况下,这真的是主要是个人喜好的问题。 The previously proposed duplicate answer解决了区分领域和属性的许多问题,但作为您所问的特定场景中的实际问题,几乎没有真正的区别。

字段名义上性能更好,因为它们可以直接访问而不需要方法调用。但是a)在很多情况下,该方法的主体将被内联,否定了这个优点,并且b)即使方法调用存在,在大多数情况下,重要性也不是很高。


所以,你需要决定:你需要防止代码通过反射修改这些值有多严重?它是否真的很重要,足以让值得用程序生成的值来包装物业的价值?如果你这样做,你多久会访问这些属性?每次调用getter时按需生成值的开销会不会影响代码的有用性?

这些只是你可以回答的问题。这里的人不可能为你回答这个问题。

+0

即使使用属性getter,运行具有完全权限的代码的人也可以简单地编辑该成员的方法指针,更改调用该属性getter时运行的代码。从根本上说,根本没有什么*可以阻止某人在该机器上运行具有完全管理权限的任意代码,特别是关于它自己的应用程序代码。 – Servy

+0

@Servy:是的,的确如此。尽管如此,我认为还有其他一些黑客行为。 .NET提供了所有需要的工具来简单地干扰字段的值,因此值得注意的是,防止与否的区别。没有必要担心无法阻止的攻击者。 –

+0

你不能真正争辩说某人会“意外地”去使用反射来修改私人支持字段的值,而没有意识到他们不打算这样做,并且确定的恶意用户正在运行完整的特权代码失败的原因。这两者之间确实没有任何关系。 – Servy