C# 使用静态只读与静态getter模拟常量

C# 使用静态只读与静态getter模拟常量,c#,C#,我正在使用第三方控件,该控件使用“奇怪的值”来区分选项列表。它们使用两个不同的属性来唯一标识每个选项 Example: "Field" + "RW" = "CheckedOutBy" "System" + "N" = "Name" "Field + "N" = "Notifier" 总共有37个不同的选项(每个选项都有两个值的不同组合,组成37个独特的选项) 我创建了一个存储这两个值的结构,我的想法是为每个选项创建一个新的结构实例 public struct ColumnCode : IEqu

我正在使用第三方控件,该控件使用“奇怪的值”来区分选项列表。它们使用两个不同的属性来唯一标识每个选项

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() { ... }
}

在任何一种情况下,我现在都可以使用
FieldOption.CheckedOutBy
FieldOption.Name
FieldOption.Notifier
等参考我的C#code中的选项,但我不确定其中一种方法是否优于另一种方法

这些选择中的一个是否比另一个更好地模拟
常量
,或者是否有更好的方法我没有考虑

我在网上读了大量的信息,仍然没有找到一个好的答案。其中一些似乎相互矛盾。很多信息表明属性优于字段,但在本文()中,Microsoft说“对预定义的对象实例使用公共静态只读字段”,所以我觉得静态只读字段是正确的选择

我也不确定反思是如何在这里发挥作用的。我想确保FieldOptions的值不能更改,即使是通过反射

在此方面的任何帮助都将不胜感激

我想确保FieldOptions的值不能更改,即使是通过反射

实现这一点的唯一方法是使用只读属性,即使这样,也只有在每次调用getter时重新实例化相应的值,例如:

public static ColumnCode CheckedOutBy
{
    get { return new ColumnCode(ColumnType.Field, "RW"); }
}
使用您所展示的语法,或者使用私有setter的auto属性,仍然存在一个支持字段,并且该支持字段仍然可以通过反射进行更改,尽管由于字段名在源代码中不可见,并且具有编译器实现相关的名称,所以更改难度稍大一些

当然,每次调用getter时重新实例化该值会对性能产生负面影响。因此,使属性深度只读(即不受反射影响)是有代价的。这个性能成本在您的场景中是否重要,您必须自己确定。这个问题没有“一个正确答案”

我在网上读了大量的信息,仍然没有找到一个好的答案。其中一些似乎相互矛盾

这是因为,除了有一些特定约束通知您的决策的场景(例如希望防止反射改变值)之外,这实际上主要是个人偏好的问题。解决了将字段与属性区分开来的许多问题,但在您所询问的特定场景中,实际情况几乎没有什么区别

字段名义上性能更好,因为它们可以直接访问,而不需要方法调用。但是a)在许多情况下,方法的主体将是内联的,从而否定了这一优势;b)即使方法调用存在,在大多数情况下,它的开销实际上也不够重要,甚至不足以测量


所以,您需要决定:您需要多大程度的保护来防止代码通过反射修改这些值?它真的足够重要,值得用程序生成的值包装属性中的值吗?如果您这样做,您多久访问一次这些属性?每次调用getter时按需生成值的开销会影响代码的有用性吗


这些问题只有你能回答。这里的人不可能替你回答这个问题。

你知道关键词的作用吗?@Jeroen Vannevel不确定我是否理解你的问题?我只是想知道C#编译器是否以不同的方式处理这些问题?是否有性能优势等。一个是静态的,另一个不是。一个是属性,另一个是字段。很明显,这些都会有差异——这取决于你对什么样的差异感兴趣。如果您指的是所有差异,那么最好的做法是阅读文档,了解
静态的效果以及字段和属性的差异。一旦你提出了一个更具体的问题,我们就可以回答,到目前为止,在帖子中没有任何迹象表明这个问题比我链接为重复的常规“公共领域与财产”主题更具体。。。我相信你在提问之前已经仔细阅读了它,但是它没有反映在文章中-如果你觉得需要重新打开,请确保编辑你的文章。@Phaeze性能问题应该包含度量、性能目标和作者希望看到解释/改进的具体问题。除此之外,还需要定期进行研究(特别是在讨论到死亡的问题上,如“财产访问是否内联”)。。。所以我怀疑OP是否真的会问这个问题(因为文章中没有显示任何必要的信息),即使使用属性getter,以完全权限运行代码的人也可以简单地编辑该成员的方法指针,在调用该属性getter时更改代码的运行。从根本上说,您无法阻止某人在该计算机上运行具有完全管理员权限的任意代码,尤其是针对其自身的应用程序代码。@Servy:是的,确实如此。我认为,另一整个级别的黑客攻击…NET提供了容易干扰字段值所需的所有工具,因此有必要记住保护与否的区别。没有必要担心你无法阻止的攻击者。你真的无法阻止他
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");
}
public static ColumnCode CheckedOutBy
{
    get { return new ColumnCode(ColumnType.Field, "RW"); }
}