亲爱的,这个问题已经被问过了,但在答案中,没有解释我所看到的问题.
问题:C#编程指南说:
静态构造函数用于初始化任何静态数据,或执行仅需执行一次的特定操作.在创建第一个实例或引用任何静态成员之前自动调用它.
特别是,在创建类的任何实例之前调用静态构造函数.(这不能确保静态构造函数在创建实例之前完成,但这是另一回事.)
我们来看一下示例代码:
using System;
public class Test
{
static public Test test = new Test();
static Test()
{
Console.WriteLine("static Test()");
}
public Test()
{
Console.WriteLine("new Test()");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Main() started");
Console.WriteLine("Test.test = " + Test.test);
Console.WriteLine("Main() finished");
}
}
Run Code Online (Sandbox Code Playgroud)
它输出:
Main()启动
新的Test()
static Test()
Test.test = Test
Main()完成
因此,我们可以看到实例构造函数在静态构造函数启动之前完成(因此创建了一个实例).这不符合指南吗?也许静态字段的初始化被认为是静态构造函数的隐式部分?
以下程序的输出是:
Non-Static
Static
Non-Static
Run Code Online (Sandbox Code Playgroud)
这是编译器错误吗?我期望:
Static
Non-Static
Non-Static
Run Code Online (Sandbox Code Playgroud)
因为我认为静态构造函数总是在非静态构造函数之前被调用.
我使用.net 3.5和.net 4.0对Visual Studio 2010进行了测试.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StaticConstructorBug
{
class Program
{
static void Main(string[] args)
{
var mc = new MyClass();
Console.ReadKey();
}
}
public class MyClass
{
public MyClass()
{
Console.WriteLine("Non-static");
}
static MyClass()
{
Console.WriteLine("Static");
}
public static MyClass aVar = new MyClass();
}
}
Run Code Online (Sandbox Code Playgroud) 根据Jon Skeet的artice C#和beforefieldinit以及When中的讨论,是一个在C#中调用的静态构造函数?必须在首次调用类的方法之前调用静态构造函数.
由于某些原因,以下代码不会出现此行为:
namespace AbstractAndStatic
{
class Program
{
static void Main(string[] args)
{
StaticClass.Equals(1,2);
StaticClass.foo();
}
}
static class StaticClass : Object
{
public static void foo()
{
Console.WriteLine("Static");
}
static StaticClass()
{
Console.WriteLine("static constructor");
}
}
class TestClass
{
public void deb()
{
Console.WriteLine("Test Class Debug");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Visual Studio调试器调试上面的代码.当StaticClass.Equals(1,2);在Main方法中执行语句时,不会StaticClass.foo();调用静态构造函数,但是在执行时它会调用静态构造函数,然后调用foo方法.
我很困惑,为什么它没有在执行时第一次调用StaticClass.Equals(1,2);.
我可能会在这里得到一些downvotes,但我实际上通过正常搜索发现了相互矛盾的信息,并希望得到其他人也能轻易找到的确定答案.
给出当前C#中的属性:
public static IEnumerable<string> foo { get; set; } = new string[] { "bar", "bar2" };
Run Code Online (Sandbox Code Playgroud)
我们知道默认值foo将返回上面的数组.如果指定了其他值,则不再使用默认值.但是,如果案例是:
public static IEnumerable<string> foo { get; set; } = GetMyStrings();
Run Code Online (Sandbox Code Playgroud)
我的想法是这个功能如下:
if(foo == null) { foo = GetMyStrings();}
Run Code Online (Sandbox Code Playgroud)
并且foo将保留从GetMyStrings()对象生命周期的第一次运行开始的值,除非被手动赋值.
我的同事坚持认为这可能是一个GC问题,并且结果GetMyStrings()会超出范围并被收集,"重新整理"参数并GetMyStrings()在对象的生命周期内引起多次调用.
我们哪个是正确的?
我正在用C#编写一个Console应用程序.当应用程序运行时,我需要它在做任何工作之前检查一些事情,例如是否存在某些设置和目录.我有一个存储的静态类Logging.cs,我已经将检查放在这个类的构造函数中,但它似乎永远不会被调用.
这是一个非常基本的例子:
Program.cs中
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Started application");
Console.ReadKey(); // Stops the application exiting so I can read the output
}
}
Run Code Online (Sandbox Code Playgroud)
Logging.cs
internal static class Logging
{
static Logging()
{
// The checks are all here, for the demo we'll just use WriteLine
Console.WriteLine("Logging constructor");
}
}
Run Code Online (Sandbox Code Playgroud)
预期的控制台输出:
已启动应用程序
日志记录构造函数< - 此行永远不会出现
我知道我可以在Logging被DoStartupChecks调用的类中创建一个静态方法,并Main在Program.cs中调用它,但是我想知道我在这里做错了什么.也许答案是创建方法并调用它但我想先了解为什么上面的例子是错误的.
假设我们在类中有一个静态构造函数,一个普通的构造函数和一个静态方法.
在Main()我们的代码为:
Classname.staticmethod();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,在执行静态方法之前,哪个构造函数被称为1st?: - 静态构造函数或普通构造函数?