首先,我已阅读问题asking for the difference between fields and properties,我知道它的用途。
现在我的问题是,我想创建一个属性,我确信get和set都是空的,所以我做get; set;
。一切都很好。但是现在我意识到我刚刚创建了一个带有大写名称的公共领域,它在各方面都是相同的。
即使是使用它的论点,所以未来的代码不依赖于实现也不能说,因为我可以简单地将它作为属性并实现getter或setter。 字段和属性的语义在它定义的类之外是相同的。
所以我的问题是,当一个属性只使用get;set;
时,我应该使用字段还是属性?
所以这个:
public IEnumerable<string> Products;
在所有方面都与此相同:
public IEnumerable<string> Products { get; set; }
答案 0 :(得分:8)
当属性只使用get; set;?
时,我应该使用字段还是属性?
使用属性...出于以下实际原因,以及属性公开状态API的哲学原因,而字段公开状态实现细节。
字段和属性的语义在它定义的类之外是相同的。
那不是真的。
SomeMethod(ref x.Products)
成为财产时,使用Products
的代码将无效。)foo.Location.X = 10
是一个字段时,Location
可以正常工作(因为x.Location
被归类为一个变量)而Location
是一个属性时却没有(因为那时表达式x.Location
被归类为一个值)。如果你有一个方法(在你的邪恶的可变类型中)改变了值,那么foo.Location.DoSomething()
将在两种情况下编译,但具有不同的效果。为所有家庭带来乐趣。答案 1 :(得分:1)
取决于具体情况。我宁愿在田野上使用这个房产。您已经提到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;
}
}
}
答案 2 :(得分:0)
使用自动属性语法是首选,因为它创建具有私有支持字段的读/写属性,从而允许您更改实现(从私有标量字段更改为字典条目或其他后端与其他自定义逻辑),从而释放了&#34;类的界面&#34; (与interface
)的实现不同。
请注意,对于集合成员属性,建议将其setter设为私有,如下所示:
public IEnumerable<String> Products { get; private set;}
......只有包含类才能改变它。
另一种选择是private readonly
字段,在C#6中,您可以使用带有readonly
支持字段的自动实现属性,如下所示:
public IEnumerable<String> Products { get; } = SomeSource.GetProducts();