如何向静态类构造函数传递参数?

45

我有一个静态类和一个静态构造函数。我需要以某种方式将参数传递给这个静态类,但我不确定最佳方式是什么。 你有什么建议?

public static class MyClass {

    static MyClass() {
        DoStuff("HardCodedParameter")
    }
}

2
你可能因为错误的原因将其设为了“静态”。重新设计。 - H H
1
第一个问题确实是:为什么这个类是静态的?很少需要这样做。 - L-Four
4个回答

68

不要使用静态构造函数,而是使用静态初始化方法:

public class A
{
    private static string ParamA { get; set; }

    public static void Init(string paramA)
    {
        ParamA = paramA;
    }
}
在C#中,静态构造函数是无参数的,有几种方法可以克服这个限制。其中一种是我上面建议过的。

但是使用方法的意义何在呢?毕竟已经有了可用的 setter 方法... - meJustAndrew
2
@meJustAndrew 因为那个 setter 是 private 的。你注意到这个重要的细节了吗? :D - Matías Fidemraizer
1
@meJustAndrew 或许另一种方法是 ParamA { private get; set; }... 顺便说一下,这只是一个代码片段,用来展示如何使用一个或多个参数初始化静态类。可能一元构造函数没什么用,但如果你想覆盖将其提供给某些委托的用例,它仍然很有用... - Matías Fidemraizer
1
实际上,我没有注意到该属性是“私有的”。我试图找到一种方法来从类外部初始化一个静态只读字段,所以我找到了你的答案。不幸的是,目前在C#中似乎没有这样的机制。对于上面的评论,我很抱歉,那是我的错! - meJustAndrew
@meJustAndrew 没问题 :D 无论如何,只要提供一个 Lazy<T> 实例而不是值,您就可以模拟所需的内容。 - Matías Fidemraizer

10
根据MSDN文档,静态构造函数会在创建第一个实例之前自动调用以初始化类。因此,您无法发送任何参数。

CLR必须调用静态构造函数,但它如何知道要传递哪些参数?

因此,请不要使用静态构造函数。

以下是满足您需求的解决方法。

public class StaticClass 
{ 
  private int bar; 
  private static StaticClass _foo;

  private StaticClass() {}

  static StaticClass Create(int initialBar) 
  { 
    _foo = new StaticClass();
    _foo.bar = initialBar; 
    return _foo;
  } 
}

静态构造函数具有以下特性:

  • 静态构造函数不带访问修饰符也没有参数。在创建第一个实例或引用任何静态成员之前,静态构造函数将自动调用以初始化该类。
  • 不能直接调用静态构造函数。
  • 用户无法控制程序何时执行静态构造函数。
  • 一般情况下,使用静态构造函数的一个典型用途是当类使用日志文件时,构造函数用于将条目写入该文件。
  • 在为非托管代码创建包装类时,静态构造函数也很有用,构造函数可以调用LoadLibrary方法。
  • 如果静态构造函数抛出异常,则运行时将不会再次调用它,并且该类型将在应用程序域的生存期内保持未初始化状态。

方法 Create 应该是 public,以便调用并初始化 StaticClass - M.Hassan
你能详细解释一下你的代码吗?在我看来,这只是一个单例模式,减去了检查_foo是否为对象的空值检查。如果没有这个空值检查,这将允许所有调用Create()的调用者在新实例被分配给静态变量_foo时保留StaticClass对象的孤立内存,我是对的吗?谢谢! - Stokely

0
如果你说的“HardCodedParameter”是指硬编码,那么你可以使用常量。
public static class YoursClass
{ 
    public const string AnotherHardCodedParam = "Foo";
}

public static class MyClass
{
    private const string HardCodedParam = "FooBar";

    static MyClass()
    {
        DoStuff(MyClass.HardCodedParam);
        DoStuff(YoursClass.AnotherHardCodedParam);
    }
}

此外,您还可以使用静态只读属性。


0
非静态类上的构造函数有一个好处,就是确保在实际使用之前它们被正确初始化。
由于静态类没有这个好处,你必须自己确保它们被初始化。
使用一个明显的名称的静态构造函数,然后在你的静态过程的相关部分检查是否已经执行了初始化。 下面的示例假设您想要使用一个表单对象来“初始化”您的静态类。
    public static class MyClass
    {
        private static Form FormMain { get; set; }

        public static void Init(Form initForm)
        {
            FormMain = initForm;
        }

        private static bool InitCheck()
        {
            return FormMain != null ? true: false;
        }

        public static void DoStuff()
        {
            if (InitCheck())
            {
                // Do your things
            }
            else
            {
                throw new Exception("Object reference not set to an instance of an object");
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接