C# 静态构造函数调用了两次
以前我有一个C# 静态构造函数调用了两次,c#,arrays,list,constructor,static,C#,Arrays,List,Constructor,Static,以前我有一个static toup()方法,我想用基类的静态构造函数来代替它,因为正如msdn所说,它“只执行一次”。 在构造函数中保留派生类的初始化并只执行一次,有什么解决方案吗 class BaseClass<T> { static BaseClass() { for (byte i = 0; i < 2; i++) { var temp = new Junction<byte>[2] {
static toup()
方法,我想用基类的静态构造函数来代替它,因为正如msdn所说,它“只执行一次”。在构造函数中保留派生类的初始化并只执行一次,有什么解决方案吗
class BaseClass<T>
{
static BaseClass()
{
for (byte i = 0; i < 2; i++)
{
var temp = new Junction<byte>[2] { new Level2<byte>(), new OtherLevel2<byte>() };
Program.myList.Add(temp);
}
Console.WriteLine("static BaseClass()");
}
}
abstract class Junction<T> : BaseClass<T> { }
sealed class Level2<T> : Junction<T> { }
sealed class OtherLevel2<T> : Junction<T> { }
class Program
{
internal static List<Junction<byte>[]> myList = new List<Junction<byte>[]>();
static Program()
{
BaseClass<object> callTheStaticMethod = new BaseClass<object>();
}
static void Main()
{
Console.WriteLine("myList.Count = " + myList.Count);
Console.ReadLine();
}
}
Output:
static BaseClass()
static BaseClass()
myList.Count = 4
类基类
{
静态基类()
{
用于(字节i=0;i<2;i++)
{
var temp=new Junction[2]{new Level2(),new OtherLevel2()};
Program.myList.Add(temp);
}
WriteLine(“静态基类()”);
}
}
抽象类连接:基类{}
密封类级别2:连接{}
密封类OtherLevel2:连接{}
班级计划
{
内部静态列表myList=新列表();
静态程序()
{
BaseClass调用StaticMethod=新的BaseClass();
}
静态void Main()
{
Console.WriteLine(“myList.Count=“+myList.Count”);
Console.ReadLine();
}
}
输出:
静态基类()
静态基类()
myList.Count=4
静态构造只调用一次。也就是说,每种类型一次
每次将基类
与不同的类型参数一起使用时,这是一种完全不同的类型。因此,Junction
,它继承了基类
,是与基类
不同的类型。调用基类
的静态构造函数,以及基类
的静态构造函数
从你的问题来看,你并不清楚你真正想要达到的目标是什么。我要说的是,在静态构造函数中使用Junction
强烈表明您的类根本不是泛型的。基类
的任何其他使用必然仍然依赖于连接
,因此基类
。这可能会否定您认为通过使类成为泛型类将获得的任何好处
通过将静态构造函数移动到BaseClass
继承的非泛型基类,可以强制静态构造函数只执行一次。例如:
class BaseClass { /* static constructor here */ }
class BaseClass<T> : BaseClass { /* other stuff */ }
class基类{/*此处为静态构造函数*/}
类基类:基类{/*其他东西*/}
但是考虑到类中缺乏通用性,这是否真的会有很大帮助还不清楚。这里似乎有一个更广泛的设计缺陷需要解决。问题是在类型化基类中有静态初始值设定项。问题是
BaseClass
和BaseClass
被认为是两种不同的类型。实际的类是在编译时生成的,因此编译器会为每个变体复制静态初始值设定项
如果将静态初始值设定项中的最后一行更改为包含类型名称,则可以更好地了解此问题
在.Net 4.6中,可以执行以下操作:
Console.WriteLine($"static BaseClass<{nameof(T)}>()");
string typeName = typeof(T).FullName;
Console.WriteLine(string.Format("static BaseClass<{0}>()", typeName));
Console.WriteLine($“static BaseClass()”);
在.Net 4.0或更高版本中,您可以执行以下操作:
Console.WriteLine($"static BaseClass<{nameof(T)}>()");
string typeName = typeof(T).FullName;
Console.WriteLine(string.Format("static BaseClass<{0}>()", typeName));
string typeName=typeof(T).FullName;
WriteLine(string.Format(“staticbaseclass()”,typeName));
要解决此问题,请在没有类型参数的标准类中执行静态初始化。在这种情况下,您可以简单地从基类中删除
类型参数。例如:
class BaseClass
{
static BaseClass()
{
for (byte i = 0; i < 2; i++)
{
var temp = new Junction<byte>[2] { new Level2<byte>(), new OtherLevel2<byte>() };
Program.myList.Add(temp);
}
Console.WriteLine($"static BaseClass<{nameof(T)}>()");
}
}
abstract class Junction<T> : BaseClass { }
sealed class Level2<T> : Junction<T> { }
sealed class OtherLevel2<T> : Junction<T> { }
类基类
{
静态基类()
{
用于(字节i=0;i<2;i++)
{
var temp=new Junction[2]{new Level2(),new OtherLevel2()};
Program.myList.Add(temp);
}
Console.WriteLine($“static BaseClass()”);
}
}
抽象类连接:基类{}
密封类级别2:连接{}
密封类OtherLevel2:连接{}
我认为您的想法是正确的,但是您的术语(“类型化”vs“没有类型的类”)是非标准的,对于泛型来说非常不清楚。我没有看到任何地方我指的是没有类型的类。我很难理解你在评论中的意思。那是你上一段的直接引述。好的,我现在明白了。清理语言。“底线是,每次向泛型提供类型参数时,都会有一个对静态初始值设定项的新调用”——没错。但是,按照您解释的方式,听起来好像您在说静态构造函数中的代码(实际上,类型的所有代码)对于每个不同的T
都是重复的。当T
是一个引用类型时,这是不正确的。我清除了所有不必要的代码,这就是为什么看起来是泛型的。只是学习并尝试使用泛型。我没有想到两个不同的参数会创建两个不同的类型,但现在看起来很明显。非常感谢。它起作用了。