之前我有一个static TopUp()
方法,我想用Baseclass的静态构造函数替换它,因为它只执行一次"正如msdn所述
msdn: Static Constuctor
保留派生类的任何解决方案'在构造函数中初始化并只执行一次?
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
答案 0 :(得分:2)
您的静态构造仅被调用一次。每种类型一次,即。
每次使用不同类型参数的BaseClass<T>
时,这都是完全不同的类型。因此,继承Junction<byte>
的{{1}}与BaseClass<byte>
的类型不同。调用BaseClass<object>
的静态构造函数,以及BaseClass<byte>
的静态构造函数。
从你的问题来看,你真正想要实现的是什么并不是很清楚。我会说,在静态构造函数中使用BaseClass<object>
强烈暗示你的类根本不是通用的。 Junction<byte>
的任何其他用途仍然必须依赖BaseClass<T>
,因此Junction<byte>
。这可能会否定你认为通过使类通用而获得的任何好处。
您可以通过将静态构造函数移动到BaseClass<byte>
继承的非泛型基类来强制执行一次。 E.g:
BaseClass<T>
但鉴于课堂上缺乏通用性,我们并不清楚这会有多大帮助。这里似乎存在一个应该解决的更广泛的设计缺陷。
答案 1 :(得分:1)
问题是您在类型基类中拥有静态初始值设定项。问题是BaseClass<string>
和BaseClass<int>
被认为是两种不同的类型。实际的类是在编译时生成的,因此编译器会为每个变体复制静态初始化程序。
如果您更改静态初始值设定项中的最后一行以包含该类型的名称,您将能够更好地了解此问题。
在.Net 4.6中,你可以这样做:
Console.WriteLine($"static BaseClass<{nameof(T)}>()");
在.Net 4.0或更高版本中,您可以执行此操作:
string typeName = typeof(T).FullName;
Console.WriteLine(string.Format("static BaseClass<{0}>()", typeName));
要解决您的问题,请在没有type参数的标准类中进行静态初始化。在这种情况下,您只需从BaseClass中删除<T>
类型参数即可。例如:
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> { }