我应该使用字段还是属性
本文关键字:属性 字段 我应该 | 更新日期: 2023-09-27 18:20:37
首先,我已经阅读了询问字段和属性之间区别的问题,我知道它的用途。
现在我的问题是,我想创建一个属性,我确信get和set都是空的,所以我做了get; set;
。一切都很好。但现在我意识到,我刚刚制作了一个大写名称的公共领域,它在各个方面都是一样的。
即使是使用它以使未来的代码不依赖于实现的论点也不能说出来,因为我可以简单地将其作为一个属性并实现getter或setter字段和属性的语义在其定义的类之外是相同的。
所以我的问题是,当一个属性只使用get;set;
时,我应该使用字段还是属性?
所以这个:
public IEnumerable<string> Products;
在所有方面都与此相同:
public IEnumerable<string> Products { get; set; }
当一个属性只使用get时,我应该使用字段或属性吗;设置
使用属性。。。出于以下实际原因,以及出于以下哲学原因:属性公开状态API,而字段公开状态实现细节。
字段和属性的语义在其定义的类之外是相同的。
这不是真的。
- 通过反射可以看到差异,这通常非常重要。例如,许多绑定框架不使用字段,只使用属性
- 您可以通过ref传递可变字段,但不能传递属性,因此将字段更改为属性会破坏源代码的兼容性。(当
Products
成为属性时,使用SomeMethod(ref x.Products)
的代码将无效。) - 将字段更改为属性也会破坏二进制兼容性,因此,如果程序集X是根据程序集Y v1.0构建的,并且您将字段更改成程序集Y v1的属性,则需要重新生成程序集X,否则它将无法正确执行
- 如果您有一个可变的值类型(请不要这样做),那么当
Location
是字段时(因为x.Location
被分类为变量),编写foo.Location.X = 10
是有效的,而当Location
是属性时(因为表达式x.Location
被分类为值),则不起作用。如果你有一个方法(在你的邪恶可变类型中)会改变值,那么foo.Location.DoSomething()
在这两种情况下都会编译,但效果不同。全家都很开心
这取决于具体情况。我更愿意使用这处房产而不是田地。您已经提到public IEnumerable<string> Products;
和public IEnumerable<string> Products { get; set; }
是相同的,但实际上它们不是。在编译过程中,属性将被转换为两个方法(即get_Products()和set_Products)。
属性的优点是允许您在分配和返回数据之前指定自定义代码,这在字段中是不可能的。检查以下示例
public IEnumerable<string> Products
{
get
{
if(DateTime.Now.Date > Convert.ToDateTime("01-01-2016"))
{
//Return future product
return new List<string>();
}
else
{
// return current products
return new List<string>() { "testing" };
}
}
set
{
if (DateTime.Now.Date > Convert.ToDateTime("01-01-2016"))
{
//ignore assign product
Products = new List<string>();
}
else
{
// add assign product
Products = value;
}
}
}
使用auto-property语法更可取,因为它创建了一个带有专用后台字段的读/写属性,从而允许您更改实现(从专用标量字段更改为字典条目或其他具有其他自定义逻辑的后端),从而从实现中释放"类的接口"(与interface
不同)。
请注意,对于集合成员属性,建议将它们的setter设置为私有,如下所示:
public IEnumerable<String> Products { get; private set;}
这样只有包含类才能更改它。
另一种选择是private readonly
字段,在C#6中,您可以使用带有readonly
后台字段的自动实现属性,例如:
public IEnumerable<String> Products { get; } = SomeSource.GetProducts();