使用静态readonly和静态getter

时间:2016-06-21 22:14:32

标签: c#

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

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

理想情况下,我想创建一个&#34;常数&#34;对于每个选项,但由于常量不是一个选项,我想尝试模仿一个常量。

我提出的两种方法是使用静态只读字段或仅使用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");
}

在任何一种情况下,我现在可以使用FieldOption.CheckedOutByFieldOption.NameFieldOption.Notifier等参考我的C#代码中的选项,但我不确定一种方法是否优于另一种方法。

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

我在互联网上阅读了大量信息,但仍然没有得到一个好的答案。其中一些似乎是相互矛盾的。许多信息表明赞成字段上的属性,但在本文中(https://msdn.microsoft.com/en-us/library/ms229057(v=vs.110).aspx)Microsoft表示&#34; DO使用公共静态只读字段来预定义对象实例&#34;所以我觉得静态只读字段是正确的选择。

我也不确定反射是如何发挥作用的。我想确保即使通过反射也无法更改FieldOptions的值。

对此的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

  

我想确保无法更改FieldOptions的值,即使通过反射

也是如此

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

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

使用您显示的语法或使用私有设置器的自动属性,仍然有一个支持字段,并且仍然可以通过反射更改该支持字段,尽管稍微有点困难,因为字段名称在源代码,并具有依赖于编译器实现的名称。

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

  

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

这是因为,除了你有一些特定约束通知你的决定的情况(比如想要阻止反思能够改变价值),这实际上是个人偏好的问题。 The previously proposed duplicate answer解决了区分字段和属性的许多问题,但作为您所询问的特定场景中的实际问题,实际上没有什么区别。

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


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

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

相关问题