据我所知,你无法将参数传递给C#中的静态构造函数。 但是,在创建类的实例之前,我确实需要传递2个参数并将它们分配给静态字段。我该怎么做呢?
答案 0 :(得分:7)
这可能需要......工厂方法!
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”是否已初始化(<或p>)
答案 1 :(得分:4)
您不能将参数传递给静态构造函数,但您可以通过泛型类型参数将参数传递给类本身。
然而,这个想法有点疯狂,无论如何我都会抛弃它。
使类具有通用性(使用将提供参数类型的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<TParameter> 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;
}
}
//e.g, 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<MyCustomParameterType> { }
//then you'd use the type like this:
public static void main()
{
var instance = new MyType<MyCustomParameterType>();
//or this:
var instance2 = new MyType2();
}
我确实认为采用自定义类型属性的解决方案适用于类型参数,但这很容易成为更好的方法。但是,您现在将使用您的类始终使用通用参数类型(除非您可以使用派生+特化技巧) - 可能对您的喜好太笨拙。
我也比这里介绍的其他解决方案更喜欢这个,因为它不需要为静态初始化创建任何变通方法 - 您仍然可以使用.Net保证单次初始化。
提醒您 - 您应该检查一下您的结构吗?
所有这一切 - 记住,但是,因为你只能参数化静态一次(或者在这种情况下,每个唯一参数化的静态通用) - 我会问自己为什么不只是拉取获得参数的代码给出到静态,并将其放在静态构造函数中?这样你实际上不必诉诸这样的奇怪模式!
答案 2 :(得分:2)
我认为你是指一个班级的静态成员?在这种情况下,您可以这样做:
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.