【问题标题】:Default value for user defined class in C#C#中用户定义类的默认值
【发布时间】:2010-12-27 13:36:39
【问题描述】:

我看到一些代码会返回默认值,所以我想知道对于用户定义的类,编译器将如何定义其默认值?

【问题讨论】:

  • 澄清一下:所有类(包括您创建的类)都将默认为null。数值类型默认为零,结构由实现定义(值在构造函数中设置)。
  • 实际上,结构体有一个不能被覆盖的隐式默认构造函数,其中零是结构体使用的内存,所以默认值仍然是编译器定义的,而不是实现定义的。
  • 重要区别:类成员用它们的默认值初始化。未初始化的局部函数变量只会给出编译器错误;)

标签: c# default-value


【解决方案1】:

为了配合其余部分,它将是 null,但我还要补充一点,您可以使用 default 获取任何类型的默认值

default(MyClass) // null
default(int) // 0

在使用泛型时特别有用;如果您的返回类型是 T 并且您不想假设它可以为空,您可能想要返回 default(T)

【讨论】:

【解决方案2】:

class 的默认值为 null

【讨论】:

    【解决方案3】:

    注意:DefaultValueAttribute 不会导致成员使用属性值自动初始化。您必须在代码中设置初始值。

    您可以使用DefaultValueAttribute 来装饰您的房产。

    private bool myVal = false;
    
    [DefaultValue(false)]
    public bool MyProperty
    {
        get
        {
           return myVal;
        }
        set
        {
           myVal = value;
        }
     }
    

    我知道这并不能回答您的问题,只是想将其添加为相关信息。

    欲了解更多信息,请参阅http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

    【讨论】:

    • 正如页面所说,DefaultValue 只是 VS 的视觉设计师使用的东西。它与实际初始化完全无关;这只是它应该如何初始化的“提示”。
    【解决方案4】:

    类的默认值为null。对于结构体,默认值与实例化结构体的默认无参数构造函数时得到的值相同(顺便说一下不能覆盖)。相同的规则递归地应用于类或结构中包含的所有字段。

    【讨论】:

      【解决方案5】:

      我会将这个“默认”类实例设为字段而不是属性,就像 System.String.Empty 的样子:

      public class Person 
      {
          public string Name { get; set; }
          public string Address { get; set; }
      
          public static readonly Person Default = new Person() 
          {
              Name = "Some Name",
              Address = "Some Address"
          };
      }
      
      ...
      
      public static void Main(string[] args)
      {
          string address = String.Empty;
      
          Person person = Person.Default;
      
          //the rest of your code
      }
      

      【讨论】:

        【解决方案6】:

        如果您想知道为什么没有允许您以某种方式为类定义非空默认值的语言功能,请记住类是“引用类型”。引用类型是对已分配内存的引用,或者换句话说,除了 null 之外的任何内容都是需要分配内存的该对象的构造实例。所以现在考虑如何将“default”关键字集成到 .NET 中以便它适用于类,想象一下可以考虑的两种实现:

        1. 您可以定义一个标记为默认值的静态实例。也许“默认”变得像一个访问修饰符(例如公共默认只读等)。这可能行得通,也许。但它真的是一个有价值的语言特性吗?至少这样,每个“默认值”都会指向同一个静态内存实例。

        2. 如果每次在类上使用 default 关键字时都会调用默认构造函数会怎样?这会很糟糕,因为如果您没有覆盖 Equals 以不比较引用,两个默认值可能彼此不相等,而且由于内存管理和内存分配性能受到影响,以及来自构造函数的副作用也很糟糕。

        总而言之,我认为这是我们真正不想要的语言功能。而 default(MyClass) 将始终 == null。

        【讨论】:

        • 很好的解释。当 IDE 建议用default(T) 替换通用<T>null 时,我的印象是default 只是作为null 的替代品。
        【解决方案7】:

        如果是引用类型,则默认值为null,如果是值类型,则视情况而定。

        【讨论】:

          【解决方案8】:
          Assert.IsTrue(default(MyClass) == null);
          

          【讨论】:

          • 这个断言的目的是什么?
          【解决方案9】:

          对于引用类型或可为空的值类型,默认值为null

          Person person = default; // = null
          IEnumerable<Person> people = default; // = null
          int? value = default; // = null
          

          对于值类型,取决于它是哪种值类型:

          int value = default; // = 0
          DateTime dateTime = default; // = 1/1/0001 12:00:00 AM
          Guid id = default; // = 00000000-0000-0000-0000-000000000000
          

          【讨论】:

            【解决方案10】:

            希望能节省一些其他人的时间。

            现在明显的选择(为此我仍然需要在谷歌上搜索一下,因为首先登陆了这个主题)是编写一个扩展,它可以帮助你初始化一个类,不管它本身的复杂性(比如构造函数 getter/setter,防止简单的默认值直接赋值)。

            稍微修改一下之前的答案:

            public class Person 
            {
                public string Name { get; set; }
                public string Address { get; set; }
            
                public static readonly Person Default = new Person() 
                {
                    Name = "Some Name",
                    Address = "Some Address"
                };
            }
            

            =>

            public class Person 
            {
                public string Name { get; set; }
                public string Address { get; set; }
            }
            public static class PersonExtentions
            {
                public static Person withDefaults(this Person obj) {
                  obj.Name = "John Doe";
                  return obj;
                }
            }
            

            然后

            Person x = new Person.withDefaults();
            

            【讨论】:

              猜你喜欢
              • 2016-10-24
              • 2021-03-04
              • 1970-01-01
              • 1970-01-01
              • 2021-12-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多