静态列表显示为空

时间:2019-03-13 06:44:27

标签: c#

我有一个称为常量的静态类。

public static class Constants
{
    public static string sampleString= "";
    public static List<int> sampleList= new List<int> {1,2,3};
}

如果我在外面调用我的静态列表: Constants.sampleList它给了我 null异常,但是Constants.sampleString可以被称为没有问题

我在这里想念东西吗?

5 个答案:

答案 0 :(得分:1)

没有奇迹,如果sampleListnull(并且您抛出了异常),则可以在某处将null分配给它。 尽量不要暴露 public 字段,这会使Constants容易受到攻击:

  public static class Constants
  {
      public static string sampleString = "";
      public static List<int> sampleList = new List<int> {1,2,3};
  }

  ...

  Constants.sampleList = null;   // We can easly assign null

  ...

  Constants.sampleList.Add(123); // <- And have an unxpected exception

但是要么将它们变成 properties

  public static class Constants
  {
      private static string s_SampleString = "";
      private static List<int> s_SampleList = new List<int> {1,2,3}; 

      public static string sampleString {
        get {return s_SampleString;}
        set {s_SampleString = value ?? "";}
      }

      public static List<int> sampleList {
        get {return s_SampleList;}
        // I doubt you actually want set here
        set {s_SampleList = value ?? new List<int>();}  
      }
  }

或者至少将字段标记为readonly(您只能分配一次):

  public static class Constants
  {
      private static string s_SampleString = "";

      public static string sampleString {
        get {return s_SampleString;}
        set {s_SampleString = value ?? "";}
      }

      // Manipulate with me, but not reassign
      public static readonly List<int> sampleList = new List<int> {1,2,3}; 
  }

无论哪种情况,您仍然可以使用列表进行操作:

  Constants.sampleList.Add(4);
  Constants.sampleList.RemoveAt(0);

但是您可以避免向列表分配null:分配空列表(带有属性的代码),否则会出现编译时错误(带有readonly的代码)

答案 1 :(得分:1)

当我运行此代码时:

void Main()
{
    Console.WriteLine(Constants.sampleList.Contains(1));
}

public static class Constants
{
    public static string sampleString= "";
    public static List<int> sampleList= new List<int> {1,2,3};
}

我在控制台上收到True。您需要提供代码来证明您所面临的问题。

答案 2 :(得分:1)

不确定这是否与我们的情况相同,但是我们有一个可以从配置访问密钥的类

string sampleString = WebConfigurationManager.AppSettings["SampleString"]

由于一些合并问题,示例字符串已从我们的web.config中删除。当访问变量下面的类中的任何变量时,会发生空指针错误。

在配置中添加密钥即可解决此问题。

答案 3 :(得分:0)

如果将readonly关键字添加到方法中。该方法只能在构造函数内部或在属性声明阶段实例化。

public static readonly List<int> sampleList= new List<int> {1,2,3};

如果您尝试重新初始化sampleList或对public static readonly List<int> SampleList {get; set;} = new List<int> {1,2,3}; 进行新的赋值,C#编译器将为您提供编译器错误。

最好还是使用Property

{{1}}

答案 4 :(得分:-1)

就我而言,我在结构中定义了一个 private static readonly Dictionary<byte, string> 来保存预定义的常量。这通常可以正常工作,但是我还在我的结构中定义了一个 MinValue 来表示一段数据的最小值。以这种方式完成后,静态字典未初始化,除非在静态 MinValue 属性上方定义。我可能对编译器的要求有点高,应该重构它。

很难在大型结构中进行诊断,因为我没想到 C# 会出现这种行为。重现示例:

public struct MyStruct
{
    public string Str;

    public static readonly MyStruct MinValue = new MyStruct(0);

    public MyStruct(byte val)
    {
        Str = _predefinedValues[val]; // null reference exception
    }

    private static readonly Dictionary<byte, string> _predefinedValues = new Dictionary<byte, string>()
    {
        {0x00, "test 1"},
        {0x01, "test 2"},
        {0x02, "test 3"},
    };

}

这里的解决方案是双重的:

  1. 不对结构调用任何构造函数,并在不访问 _predefinedValues 列表的情况下显式设置每个字段。
  2. 或者,将列表向上移动到 MinValue 字段声明上方实际上也能修复它(奇怪吧?)

我怀疑在尝试分配它时堆栈上发生了一些奇怪的事情,这可能是一件奇怪的事情。