【问题标题】:c# initialize static variable from different classesc#从不同的类初始化静态变量
【发布时间】:2019-11-26 10:24:46
【问题描述】:

我拥有的是:

public static class IDs {

    public static string someID { get; set; }

    static IDs() {
        log.info(someID);
        // use someID here
    }
}

public class otherClass {

     public void otherMethod(string sym) {
         IDs.someID = sym;
     }
}

然后像这样使用otherClass 的实例:

otherClassInstance.otherMethod("someStringSymbol");

我没有任何构建错误,但 log.info(someID); 正在打印 null
我期待它是someStringSymbol

【问题讨论】:

  • 未定义静态构造函数发生的顺序。 (静态 initializers 发生的顺序是,但即使那样也不是跨类。)定义不明确的顺序,以及几乎不可能从它们中的错误中恢复,应该是一个强烈的抑制因素使用静态构造函数期间,尤其是当您要引入依赖项时。更喜欢具有明确初始化时间的实例,即使您制作了那些单例。
  • 您发布的代码无法编译。请使用minimal, reproducible example 编辑您的问题。
  • 在设置someID 属性之前调用静态构造函数。这是预期的行为。在类型初始化之前不能设置属性。
  • 你想达到什么目的?

标签: c#


【解决方案1】:

这是因为静态构造函数is called automatically before the first instance is created or any static members are referenced.

这意味着当otherClass的实例调用IDs.someID = sym;第一个执行的操作是静态构造函数,即static IDs()中的代码。

此时静态变量还没有初始化,你基本上是在执行log.info(null);

静态构造函数完成后,变量被初始化,所以在IDs第一次引用之后,你应该可以在otherMethod中看到它的值。


鉴于 OP 的要求:

我想在 switch 语句中使用someID 中传递的值

解决方案可以是在设置新值时简单地执行一个静态方法,在 explicit getters and setters 的帮助下:

public static class IDs
{
    private static string _someID; // backing field

    public static string SomeID
    {
        get { return _someID; }

        set
        {
            _someID = value;
            DoSomethingWithSomeID();
        }
    }

    private static DoSomethingWithSomeID()
    {
        // Use SomeID here.

        switch (IDs.SomeID)
        {
            ...
        }
    }
}

public class OtherClass
{
    public void OtherMethod(string sym)
    {
        // This will set a new value to the property
        // and invoke DoSomethingWithSomeID.
        IDs.SomeID = sym;
    }
}

每当有人将新值设置为SomeID 时,都会调用DoSomethingWithSomeID

【讨论】:

  • 那么我们如何在执行构造函数static IDs的同时初始化someID
  • 你只想记录someID的值吗?
  • 不,我想在switch 语句中使用它,并根据从someStringSymbol 传入的someID 中的值,构造xPath 中的几个UI 元素IDs
  • 这些 UI 元素的引用是静态字段吗?
  • 是的,这就是我目前面临的挑战。最初我使用静态,但现在随着需求的变化,我需要动态构造xPath
【解决方案2】:

我认为您尝试做的事情不适合静态类。我会尝试以下方法

public class IDs{

    public string someID{ get; set; }

    public IDs(string someId){
        this.someID = someId;
        log.info(this.someID);
           //use someID here
    }
}

pulic class otherClass{


     public otherMethod(string sym){
                IDs id = new IDs(sym);
            }
      }

public class anotherClass{

                //access instance of otherClass in wrp and call otherMethod()
               wrp.otherMethod("someStringSymbol")
         }

【讨论】:

  • 如果我这样做,那么我将不得不在几个地方更改IDs 的引用,因为我将它从静态变为非静态。我想避免这种情况。
猜你喜欢
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
相关资源
最近更新 更多