鉴于以下代码,为什么在"Main"的第一行之后调用"Outer"的静态构造函数?
namespace StaticTester
{
class Program
{
static void Main( string[] args )
{
Outer.Inner.Go();
Console.WriteLine();
Outer.Go();
Console.ReadLine();
}
}
public static partial class Outer
{
static Outer()
{
Console.Write( "In Outer's static constructor\n" );
}
public static void Go()
{
Console.Write( "Outer Go\n" );
}
public static class Inner
{
static Inner()
{
Console.Write( "In Inner's static constructor\n" );
}
public static void Go()
{
Console.Write( "Inner Go\n" );
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 这是一个与 C++ 中对象初始化相关的问题。
我有一组类(不是实例),它们继承自一个公共基类,我需要它们在程序启动时在容器(特别是地图)中注册有关它们自己的信息。
问题是我需要它是动态的。容器定义在一个独立的项目中,不同于类。我宁愿避免制作库的多个硬编码版本,每个使用它的程序中的每一组类都有一个。
我想过在每个子类中都有一个特殊类的静态实例,这将在其构造函数中进行注册。但是,我发现没有办法保证在构造这些对象之前构造容器。
我还应该注意,在创建这些子类的任何实例之前,容器中关于子类的信息应该可用。
有没有办法做到这一点,或者在一般情况下模仿 C++ 中的静态构造函数?
class Bus<T>
{
static Bus()
{
foreach(FieldInfo fi in typeof(T).GetFields())
{
if(fi.FieldType == typeof(Argument))
{
fi.SetValue(typeof(T), new Argument("busyname", "busyvalue"));
}
}
}
}
class Buss : Bus<Buss>
{
public static Argument field;
}
Run Code Online (Sandbox Code Playgroud)
有什么想法可以使这项工作有效,以便对Buss中的static字段的引用触发Bus中的静态构造函数吗?
我正和一位朋友辩论,他说静态构造函数可以让位于竞争条件,因为静态构造函数可以被多次调用.似乎这只能在高容量多线程环境中发生.这甚至可能吗?
我找不到任何证明他错的文件.有没有人对此有任何见解?
谢谢!
我有一个带有静态构造函数的类,我用它来读取 app.config 值。如何使用不同的配置值对类进行单元测试。我正在考虑在不同的应用程序域中运行每个测试,这样我就可以为每个测试执行静态构造函数 - 但我这里有两个问题:
1.我不知道如何在单独的应用程序域中运行每个测试,
2.如何我要在运行时更改配置设置吗?
有人可以帮我解决这个问题吗?或者谁有更好的解决方案?谢谢。
我有一个静态Configuration类负责整个系统的数据设置.它在构造函数中从注册表加载某些值,并且它的所有方法都基于这些值.如果它无法从注册表中获取值(如果应用程序尚未激活,则可能),它会抛出一个异常,转换为a TypeInitializationException,这对我很好.
我使用NUnit编写了单元测试,以确保Configuration的构造函数正确处理所有情况 - 正常值,空值,空值.每个测试使用相关值初始化注册表,然后在Configuration中调用一些方法.这就是问题所在:NUnit决定先运行Null测试.它清除注册表,初始化Configuration,抛出异常 - 一切都很好.但是,因为这是一个静态类,其构造函数只是失败了 - 它不会为其他测试重新构造类,它们都会失败.
即使没有Null测试,我也会遇到问题,因为对于所有使用它的类,配置可能(我猜)会被初始化一次.
我的问题是:我应该使用反射为每个测试重新构造类,还是应该重新设计此类以检查属性中的注册表而不是构造函数?
我正在研究一些类似这样的代码:
class A
{
static SomeClass a = new Someclass("asfae");
}
Run Code Online (Sandbox Code Playgroud)
Someclass包含必需的构造函数.这个代码编译好没有任何警告.但是我在系统中遇到代码危险:
"已经从静态构造函数和/或静态初始化器调用了Someclass ctor"
这个代码危害了系统的一部分,只是为了通过警告系统中可能存在的缺陷或系统因此而陷入不良状态来使其更好.我在网上的某处读到静态构造函数/初始化程序可以在c#中等待线程完成时陷入死锁.这与此有关吗?
我需要摆脱这个警告我该怎么做呢.由于静态函数使用它,我不能使该成员为静态.在这种情况下我该怎么做,需要帮助.
是否有可能在应用程序启动时"自动"初始化静态类?我自动意思是不需要引用属性.
我希望能够做到这一点的原因是我想在启动时自动设置应用程序的主题.
这是一个简短的片段:
static class Settings{
private static Theme _defaultTheme;
public static Theme DefaultTheme{
get{
return _defaultTheme;
}
private set{
_defaultTheme = value;
ThemeManager.SetTheme(value);
}
}
static Settings(){
DefaultTheme = Themes.SomeTheme;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以(现在就是这样)和原来的getter/setter一起去打电话
ThemeManager.SetTheme( Settings.DefaultTheme );
Run Code Online (Sandbox Code Playgroud)
在App的构造函数(它是WPF项目)中它会完成这项工作,但是,至少从我的观点来看(如果我错了请纠正我),更适合默认主题应用而不是需要明确说明它.
c# static-constructor static-classes static-initialization static-class
乔恩斯基特建议在他的单身执行,如果你需要为你的最大的懒惰单身,你应该添加静态构造函数,这将使编译器标记类型beforefieldinit.
但是,我做了一些测试,如果没有 beforefieldinit ,它似乎更懒.
代码示例(私有构造函数调用输出到控制台并验证字段是否已初始化:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public static string Stub()
{
return "123";
}
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
//static Singleton()
//{
//}
private Singleton()
{
Console.WriteLine("private ctor");
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用Singleton.Stub()时,私有构造函数没有被命中,当我取消注释静态构造函数时,总是调用私有构造函数.
这是我可以跟踪静态构造函数的唯一区别.
在我尝试理解beforefieldinit之间的区别时,我也读过Skeet 在这篇文章中的答案,尝试将false传递给DoSomething() - 无论是否有静态构造函数,私有构造函数都没有被调用.
public static void …Run Code Online (Sandbox Code Playgroud) c# ×9
unit-testing ×2
.net ×1
assemblies ×1
c++ ×1
constructor ×1
entry-point ×1
inheritance ×1
nunit ×1
singleton ×1
static ×1
static-class ×1