【问题标题】:How to fix "CA1810: Initialize reference type static fields inline" with an abstract base...?如何使用抽象基础修复“CA1810:内联初始化引用类型静态字段”......?
【发布时间】:2011-07-02 16:23:15
【问题描述】:

这是我拥有的代码的简化部分:

abstract class DataManager<TValue>
{
    protected static Dictionary<string, TValue> Values;
}

然后我有:

class TextManager : DataManager<string>
{
    static TextManager()
    {
        Values = ... // Fill with data
    }
}

而且,现在我得到的是 CA1810。我看到了一些解决方案,比如将Values 公开并将它们设置在其他地方,但我不喜欢那样,或者在TextManager 中创建一个静态方法来做同样的事情,但是在程序启动时调用,但我也不喜欢。

我认为从示例中可以明显看出,Values 每个TValue 只应填写一次。那么,您认为这里的最佳解决方案是什么?

【问题讨论】:

  • 当另一个类,比如class AnotherTextManager : DataManager&lt;string&gt; 出现并想要以不同的方式初始化值时,你会怎么做?
  • 对不起,我没有解释我不需要那个...我只需要这两个字符串、整数和List&lt;T&gt; 的管理器...我认为不需要进入更深入的细节。
  • 但是编译器是如何知道这一点的呢?
  • 那么...我可以做些什么来让编译器“理解”吗? :) 我并不是说我的代码很好,欢迎提出任何建议...... DataManager 的剩余代码无关紧要,它适用于 Values 字段,而 TextManager 有一些特定于字符串的方法。
  • 您还可以使您的属性不是静态的,并使您的 TextManager 成为单例(或者更好的是,如果您使用的是 IOC 容器,您的 TextManager 可以是在单例范围内实例化的常规类)

标签: c# inheritance static constructor abstract


【解决方案1】:

我会关闭规则。 问题是,您有一条规则,即 (AFAIK) 旨在警告您使用静态构造函数可能对性能造成影响。 我想说静态属性的初始化可以通过静态构造函数或内联(如suggested by MSDN)来完成。在您的情况下,您不能内联,因为:

  1. 您只有子类中的实际值
  2. 没有抽象静态方法之类的东西,因此您不能将实际的内联初始化委托给 TextManager。

这样就留下了静态构造函数选项,这基本上意味着关闭规则(这意味着“是的,Microsoft。我知道这可能会影响性能,但我知道我在做什么”)。

MSDN 声明:“如果性能不是问题,或者如果由静态初始化引起的全局状态更改代价高昂或必须保证在静态方法之前发生,则可以安全地禁止来自该规则的警告。调用该类型或创建该类型的实例。”

================================================ =========================

试试这个(警告:在 Mono 2.6.7 上测试,而不是 .NET):

abstract class DataManager<TValue>
{
    protected static Dictionary<string, TValue> Values=new Dictionary<string, TValue>();
}

class TextManager : DataManager<string>
{
    static TextManager()
    {
        Values.Add("test","test");
    }

    public static string test()
    {
        return Values["test"];
    }
}

class IntManager : DataManager<int>
{
    static IntManager()
    {
        Values.Add("test",1);
    }

    public static int test()
    {
        return Values["test"];
    }   
}

public static void Main (string[] args)
{
    Console.WriteLine(IntManager.test());    
    Console.WriteLine(TextManager.test());    
}

【讨论】:

    【解决方案2】:

    代码分析警告就是这样,旨在标记潜在问题的警告。如果你有充分的理由去做你所做的事情,那就去做吧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多