将静态参数传递给类

据我所知,你无法将参数传递给C#中的静态构造函数。 但是,在创建类的实例之前,我确实需要传递2个参数并将它们分配给静态字段。 我该怎么办?

这可能是一个工厂方法!

class Foo { private int bar; private static Foo _foo; private Foo() {} static Foo Create(int initialBar) { _foo = new Foo(); _foo.bar = initialBar; return _foo; } private int quux; public void Fn1() {} } 

您可能需要根据需要检查“bar”是否已初始化(或不已初始化)。

您不能将参数传递给静态构造函数,但您可以通过generics类型参数将参数传递给类本身。

然而,这个想法有点疯狂,无论如何我都会抛弃它。

使类具有通用性(使用将提供参数类型的TypeParam)并在其上放置通用约束(代码示例中的详细信息),然后派生一个新的参数类型,其中包含可用于读取所需参数值的虚拟内容成为。

 //base parameter type - provides the 'anchor' for our generic constraint later, //as well as a nice, strong-typed access to our param values. public class StaticParameterBase { public abstract string ParameterString{ get; } public abstract MyComplexType ParameterComplex { get; } } //note the use of the new() generic constraint so we know we can confidently create //an instance of the type. public class MyType where TParameter:StaticParameterBase, new() { //local copies of parameter values. Could also simply cache an instance of //TParameter and wrap around that. private static string ParameterString { get; set; } private static MyComplexType ParameterComplex { get; set; } static MyType() { var myParams = new TParameter(); ParameterString = myParams.ParameterString; ParameterComplex = myParams.ParameterComplex; } } //eg, a parameter type could be like this: public class MyCustomParameterType : StaticParameterBase { public override string ParameterString { get { return "Hello crazy world!"; } } public override MyComplexType { get { //or wherever this object would actually be obtained from. return new MyComplexType() { /*initializers etc */ }; } } } //you can also now derive from MyType<>, specialising for your desired parameter type //so you can hide the generic bit in the future (there will be limits to this one's //usefulness - especially if new constructors are added to MyType<>, as they will //have to be mirrored on this type as well). public class MyType2 : MyType { } //then you'd use the type like this: public static void main() { var instance = new MyType(); //or this: var instance2 = new MyType2(); } 

我确实考虑过采用自定义类型属性的解决方案适用于类型参数,但这很容易成为更好的方法。 但是,您现在将使用您的类始终使用通用参数类型(除非您可以使用派生+特化技巧) – 可能对您的喜好太笨拙。

我也比这里介绍的其他解决方案更喜欢这个,因为它不需要为静态初始化创建任何变通方法 – 您仍然可以使用.Net保证单次初始化。

一句警告 – 您应该检查一下您的结构吗?

所有这一切 – 记住,但是,因为你只能参数化静态一次(或者在这种情况下,每个唯一参数化的静态generics) – 我会问自己为什么不只是拉动获取参数的代码给静态,并将其放在静态构造函数中? 那样你实际上不必诉诸这样的奇怪模式!

我假设你是指一个class级的静态成员? 在这种情况下,您可以这样做:

 public class MyClass { public static int MyInt = 12; public static MyOtherClass MyOther = new MyOtherClass(); } 

保证在实例化任何类之前实例化这些静态成员。

如果您需要复杂的逻辑,请在静态构造函数中执行:

 public class MyClass { public static int MyInt; public static MyOtherClass MyOther; static MyClass() { MyInt = 12; MyOther = new MyOtherClass(); } } 

编辑

根据您的编辑,我会说在实例化类之前将值分配给它们需要的值,如下所示:

 public class MyClass { public static int MyInt; public static MyOtherClass MyOther; } // elsewhere in code, before you instantiate MyClass: MyClass.MyInt = 12; MyClass.MyOther = new MyOtherClass(); MyClass myClass = new MyClass(); 

也就是说,这种方法无法保证在实例化MyClass之前设置MyInt和MyOther。 它可以工作,但在实例化MyClass之前需要遵守规则。

您可能遵循的一种替代模式如下所示:

 public class MyClass { private static int MyInt; private static MyOtherClass MyOther; private static bool IsStaticInitialized = false; public static InitializeStatic(int myInt, MyOtherClass other) { MyInt = myInt; MyOther = other; IsStaticInitialized = true; } public MyClass() { if(!IsStaticInitialized) { throw new InvalidOperationException("Static Not Initialized"); } // other constructor logic here. } } // elsewhere in your code: MyClass.InitializeStatic(12, new MyOtherClass()); MyClass myClass = new MyClass(); // alternatiavely: MyClass myClass = new MyClass(); // runtime exception.