C# 静态类、静态构造函数和静态属性
我有一个只有静态属性和静态构造函数的静态类。当我尝试访问或设置属性的值(带有一个支持字段)时,不会调用静态构造函数。但是,如果我定义了一个静态方法并尝试调用它,则会执行构造函数 我相信属性只是语法上的糖分,在内部被翻译成方法。那么,为什么运行时会对它们进行不同的处理呢?我的类定义如下所示: 编辑:我删除了初始化_fileencodingtextinline值的代码 编辑:调用构造函数,但未设置属性。这可能是因为“静态构造函数只运行零次或一次,并且在其类型中的静态方法调用或实例创建之前运行”。伊戈尔·奥斯特罗夫斯基和埃里克·利珀特在他们的博客中解释了这一点C# 静态类、静态构造函数和静态属性,c#,C#,我有一个只有静态属性和静态构造函数的静态类。当我尝试访问或设置属性的值(带有一个支持字段)时,不会调用静态构造函数。但是,如果我定义了一个静态方法并尝试调用它,则会执行构造函数 我相信属性只是语法上的糖分,在内部被翻译成方法。那么,为什么运行时会对它们进行不同的处理呢?我的类定义如下所示: 编辑:我删除了初始化_fileencodingtextinline值的代码 编辑:调用构造函数,但未设置属性。这可能是因为“静态构造函数只运行零次或一次,并且在其类型中的静态方法调用或实例创建之前运行”。伊戈
我无法复制这个问题 下面的程序将打印
AppSettings - Static constructor called.
UTF8
正如所料
因此,答案似乎是您在测试中的某个地方犯了错误
using System;
using System.Text;
namespace Demo
{
internal static class AppSettings
{
static AppSettings()
{
FileEncodingText = "UTF8";
Console.WriteLine("AppSettings - Static constructor called.");
}
private static string _fileEncodingText = "UTF8";
public static string FileEncodingText
{
get { return _fileEncodingText; }
set
{
string oldValue = _fileEncodingText;
_fileEncodingText = value;
try
{
FileEncoding = Encoding.GetEncoding(value);
}
catch (System.Exception)
{
_fileEncodingText = oldValue;
FileEncoding = Encoding.UTF8;
}
}
}
public static Encoding FileEncoding { get; private set; }
}
class Program
{
static void Main()
{
Console.WriteLine(AppSettings.FileEncodingText);
}
}
}
当我尝试访问或设置属性的值时(有支持)
字段)未调用静态构造函数
我无法复制您看到的问题,并且上述情况似乎没有发生在我的示例中(请参见.NET FIDLE链接-)
设置FileEncodingText属性(将\u FileEncodingText
后台字段设置回UTF8)时,似乎引发了异常。这可能是你看到的原因吗
以下内容(摘自上述.NET Fiddle):
结果如下:
In constructor
Setting value: UTF8
Exception
Setting value: UTF16
Exception
UTF8
更新:
进一步深入到异常中,这是我在小提琴中看到的输出。也许值得添加一些日志来查看是否在您的端抛出异常
Run-time exception (line 45): The type initializer for 'AppSettings' threw an exception.
Stack Trace:
[System.ArgumentException: 'UTF8' is not a supported encoding name.
Parameter name: name]
at AppSettings.set_FileEncodingText(String value): line 34
at AppSettings..cctor(): line 9
[System.TypeInitializationException: The type initializer for 'AppSettings' threw an exception.]
at Program.Main(): line 45
如您所见,根据文档,当设置默认的UTF8
值时,这会在构造函数中抛出
在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类
请注意,文档中提到了“静态成员”,因此“静态属性”和“静态方法”之间没有区别[在您的案例中]您有使用示例吗?当您设置属性时会调用构造函数。如果类是静态的,我看不出使用静态构造函数的意义。特别是因为您已经将
“UTF8”
赋值给类变量。您通常会在非静态类中使用静态构造函数。属性绝对不是“语法糖”,它们被CLR很好地识别为属性而不是方法。我没有任何例外。我正在VisualStudio中调试这段代码,应用程序运行时没有任何问题。我已经在构造函数中设置了一个断点,但是断点没有命中。这很奇怪。它肯定会在链接中提供的小提琴中抛出一个异常。您是否尝试过将FileEncoding
属性设置为catch块中的异常值,并验证该属性返回其值后没有更改?是的。。如果我将它设置为某个无效值,比如“Ansi”,它会抛出一个异常,编码被设置为默认值UTF8。在这种情况下,我将它设置为某个有效值,比如windows-1252,它可以处理任何问题。哦,好的,这就回答了这些问题。我刚刚更新了我的答案,包括抛出的异常。它似乎与构造函数中设置的默认UTF8
值有关。我有一个winform应用程序,构造函数中的代码没有被调用。@Sandeep它是否是winform应用程序没有任何区别。你一定在什么地方忽视了什么。你在写。。静态构造函数执行。。但是对属性的调用不起作用。@Sandeep那么我会怀疑抛出了异常。
In constructor
Setting value: UTF8
Exception
Setting value: UTF16
Exception
UTF8
Run-time exception (line 45): The type initializer for 'AppSettings' threw an exception.
Stack Trace:
[System.ArgumentException: 'UTF8' is not a supported encoding name.
Parameter name: name]
at AppSettings.set_FileEncodingText(String value): line 34
at AppSettings..cctor(): line 9
[System.TypeInitializationException: The type initializer for 'AppSettings' threw an exception.]
at Program.Main(): line 45