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
是一个引用类型时,这是不正确的。我清除了所有不必要的代码,这就是为什么看起来是泛型的。只是学习并尝试使用泛型。我没有想到两个不同的参数会创建两个不同的类型,但现在看起来很明显。非常感谢。它起作用了。