首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >静态类、静态构造函数和静态属性

问静态类、静态构造函数和静态属性
EN

Stack Overflow用户
提问于 2016-02-29 11:36:07
回答 3查看 1.5K关注 0票数 2

我有一个只具有静态属性的静态类和一个静态构造函数。当我尝试访问或设置属性值(带有支持字段)时,静态构造函数不会被调用。但是,如果我定义了一个静态方法并试图调用它,就会执行构造函数。

我相信属性只是语法糖,在内部被翻译成方法。那么,为什么运行时对它们的处理方式不同呢?我的类定义如下:

编辑:我已经删除了初始化_fileEncodingText值的代码。

编辑:调用构造函数,但未设置属性。这可能是因为“静态构造函数精确地运行0或1次,并且在静态方法调用或创建其类型的实例之前运行”。Igor Ostrovsky和Eric Lippert在他们的博客中解释了这一点。

  1. http://blogs.msdn.com/b/pfxteam/archive/2011/05/03/10159682.aspx
  2. http://ericlippert.com/2013/01/31/the-no-lock-deadlock/ 内部静态类AppSettings { AppSettings() { FileEncodingText = "UTF8";} 私有静态字符串_fileEncodingText;公共静态字符串FileEncodingText { get {返回_fileEncodingText;} set {字符串oldValue = _fileEncodingText;_fileEncodingText =值;尝试{ FileEncoding =Encoding.GetEncoding(值);} catch (System.Exception) { _fileEncodingText = oldValue;FileEncoding = Encoding.UTF8;}})公共静态编码FileEncoding { get;私有集;} }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-29 12:40:26

当我尝试访问或设置属性值(带有支持字段)时,静态构造函数不会被调用。

我无法复制您所看到的问题,在我的示例中,上述情况似乎没有发生(请参阅.NET Fiddle链接- https://dotnetfiddle.net/ikIhw3)。

当设置FileEncodingText属性时,似乎会引发异常,该属性将_fileEncodingText后备字段设置为UTF8。这可能是你看到的原因吗?

以下内容(摘自上述.NET Fiddle):

代码语言:javascript
复制
internal static class AppSettings
{
    static AppSettings()
    {
        Console.WriteLine("In constructor");
        FileEncodingText = "UTF8";
    }

    private static string _fileEncodingText = "UTF8";
    public static string FileEncodingText
    {
        get { return _fileEncodingText; }
        set
        {
            Console.WriteLine("Setting value: " + value);
            string oldValue = _fileEncodingText;
            _fileEncodingText = value;

            try
            {
                FileEncoding = Encoding.GetEncoding(value);
            }
            catch (System.Exception)
            {
                 Console.WriteLine("Exception");
                _fileEncodingText = oldValue;
                FileEncoding = Encoding.UTF8;
            }
        }
    }

    public static Encoding FileEncoding { get; private set; }
}


public class Program
{
    public static void Main()
    {
        AppSettings.FileEncodingText = "UTF16";
        Console.WriteLine(AppSettings.FileEncodingText);
    }
}

下列产出的结果:

代码语言:javascript
复制
In constructor
Setting value: UTF8
Exception
Setting value: UTF16
Exception
UTF8

更新:

进一步钻研异常,这是我在小提琴中看到的输出。也许添加一些日志记录是值得的,看看异常是否被抛到了您的头上?

代码语言:javascript
复制
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值时,这是在构造函数中抛出的?

票数 3
EN

Stack Overflow用户

发布于 2016-02-29 12:35:57

我不能重复这个问题。

下列程序打印

代码语言:javascript
复制
AppSettings - Static constructor called.
UTF8

如预期的那样。

因此,答案似乎是你在测试中犯了一个错误。

代码语言:javascript
复制
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);
        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2016-02-29 12:51:42

根据MSDN文档

在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类。

请注意,文档中写的是“静态成员”,所以在您的情况下,“静态属性”和“静态方法”没有区别。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35698518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档