如何在C#中创建只读对象属性?
如下所示,用户可以更改只读产品字段/属性:如何在C#中创建只读对象属性?,c#,asp.net,properties,readonly,C#,Asp.net,Properties,Readonly,如下所示,用户可以更改只读产品字段/属性: class Program { static void Main(string[] args) { var product = Product.Create("Orange"); var order = Order.Create(product); order.Product.Name = "Banana"; // Main method s
class Program
{
static void Main(string[] args)
{
var product = Product.Create("Orange");
var order = Order.Create(product);
order.Product.Name = "Banana"; // Main method shouldn't be able to change any property of product!
}
}
public class Order
{
public Order(Product product)
{
this.Product = product;
}
public readonly Product Product;
public static Order Create(Product product)
{
return new Order (product);
}
}
public class Product
{
private Product(){}
public string Name { get; set; }
public static Product Create(string name)
{
return new Product { Name = name };
}
}
我认为这很基本,但似乎不是这样
如何在C#?中创建只读对象属性或字段
谢谢,关键字
readonly
阻止您将新实例放入该字段
它不会神奇地使字段中的任何对象不可变。如果你写作,你希望发生什么
readonly Product x = Product.Create();
Product y;
y = x;
y.Name = "Changed!";
如果您想要一个不可变对象,则需要通过删除所有公共setter使类本身不可变。您需要使Product private set的Name属性:
public class Product
{
private Product(){}
public string Name { get; private set; }
public static Product Create(string name)
{
return new Product { Name = name };
}
}
只读字段总是可以在构造函数中修改。如果试图在其他位置编辑该字段,则会出现编译器错误。readonly关键字表示只能在构造函数中设置该字段&该值不能更改 如果该值是引用类型,则不会使对象为只读
如果要使属性为只读,只需省略setter。您看到的问题是将
readonly
修饰符与您认为的只读属性混淆。readonly
修饰符确保只能通过初始化或构造函数将字段分配给,例如这里有readonly
的有效用法:
public class MyClass
{
private readonly int age = 27; // Valid, initialisation.
}
public class MyClass
{
private readonly int age;
public MyClass()
{
age = 27; // Valid, construction.
}
}
public class MyClass
{
private readonly int age;
public int Age { get { return age; } set { age = value; } } // Invalid, it's a readonly field.
}
order.Product = Product.Create("Apple") // <- not allowed because Product field is readonly
order.Product.Name = "Apple" // <- allowed because Name is not readonly field or private property
您发现,
Person
类本身是可变的,这意味着尽管字段Order.Product
是只读的,Person
的内部结构不是只读的。为此,如果要创建只读属性,可能需要将类型创建为不可变的,因为其内部结构/值不能更改。要更好地演示只读属性,请执行以下操作:
public class MyClass
{
private readonly int age = 27; // Valid, initialisation.
}
public class MyClass
{
private readonly int age;
public MyClass()
{
age = 27; // Valid, construction.
}
}
public class MyClass
{
private readonly int age;
public int Age { get { return age; } set { age = value; } } // Invalid, it's a readonly field.
}
order.Product = Product.Create("Apple") // <- not allowed because Product field is readonly
order.Product.Name = "Apple" // <- allowed because Name is not readonly field or private property
当然,这个解决方案的问题是:
new Product { Name = "Orange" } // <- not allowed if called from outside Product class
它们之间唯一的区别是:
order.Product.Name = "Apple" // <- not allowed
Product product = new Product { Name = "Orange" } // not allowed in solution #1 when called from outside Product, allowed in solution #2
product.Name = "Apple" // <- not allowed in solution #1 but allowed in solution #2
order.Product.Name=“苹果”//Related:这不是他的问题,尽管一开始可能并不明显Product
是只读的,他的问题是为什么他以后可以更改Product.Name
。啊,是的,我错过了主要的属性更改。我只在Order构造函数中看到它的初始化。在这种情况下,+1在SLaks上回答!