3

有没有办法自动实例化一个对象而不在构造函数中实例化它?

实际上,我有类似的东西:

public List<Object> Products { get; set; }
public MyClass()
{
    this.Products = new List<Object>();
}

但是,相反,我想直接实例化我的列表,而不用在我的类的构造函数中指定类似的内容:

public List<Object> Products = new List<Object>(); { get; set; }

有什么技巧可以做到这一点吗?

4

3 回答 3

4

我想您是在问是否可以为自动实现的属性赋予初始值。这个问题的答案是“不”。

可以编写手动属性:

private List<Product> products = new List<Product>();

public List<Product> Products
{
    get { return products; }
    set { this.products = value; }
}

你真的需要二传手吗?您是否需要客户端能够用另一个列表替换变量值?您可能会发现您只需要一个只读属性,在这种情况下您可以编写:

private readonly List<Product> products = new List<Product>();

public IList<Product> Products { get { return products; } }

请注意,在这里您仍然可以使用集合初始化程序,例如

Foo foo = new Foo
{
    Products = { new Product("foo"), new Product("bar") }
};
于 2013-02-12T19:37:30.977 回答
3

正如乔恩斯基特所说:

不幸的是,现在没有办法做到这一点。您必须在构造函数中设置值。(使用构造函数链接有助于避免重复。)

自动实现的属性现在很方便,但肯定会更好。我发现自己并不希望像只读自动实现的属性那样频繁地进行这种初始化,该属性只能在构造函数中设置并且由只读字段支持。有可能这两个都将在 C# 5 中得到修复,我强烈希望这将解决不变性问题。(我认为它们中的任何一个都没有计划用于 C# 4。)

来源:初始化 C# 自动属性


如果需要初始化property without using the constructor,则需要使用backing field.

例子

class Demo
{
    private List<object> myProperty = new List<object>();
    public List<object> MyProperty
    {
        get { return myProperty; }
        set { myProperty = value; }
    }
}
于 2013-02-12T19:37:18.503 回答
1

在 C# 中,目前没有自动生成的属性(尽管 VB.NET 自动属性可以做到这一点)。这是我经常为自己所希望的。所以你可以手动滚动你自己的属性,或者使用构造函数。

无论哪种方式,您都会有一些您希望不必编写的代码来执行此操作(没有构造函数的手动属性与具有构造函数的自动属性)。

不过,有趣的是,这两个选项之间的 IL 是不同的。当您有一个带有使用初始化器的支持字段的手动属性时,它将在 C# 中的基类构造函数之前执行:

MyClass..ctor:
IL_0000:  ldarg.0     
IL_0001:  newobj      System.Collections.Generic.List<System.Object>..ctor
IL_0006:  stfld       UserQuery+MyClass._products
IL_000B:  ldarg.0     
IL_000C:  call        System.Object..ctor
IL_0011:  nop         
IL_0012:  ret         

在构造函数中使用带有初始化的自动属性时,将在 C# 中的基类构造函数之后执行:

MyClass..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  nop         
IL_0007:  nop         
IL_0008:  ldarg.0     
IL_0009:  newobj      System.Collections.Generic.List<System.Object>..ctor
IL_000E:  call        UserQuery+MyClass.set_Products
IL_0013:  nop         
IL_0014:  nop         
IL_0015:  ret       

我只是出于好奇而这么说,因为在 .NET 中编写依赖于初始化顺序的代码可能是有风险的(初始化顺序实际上在 VB.NET 和 C# 之间有所不同)

于 2013-02-12T19:37:08.423 回答