C#基本属性理解
我正在学习C#,我遇到了以下代码C#基本属性理解,c#,C#,我正在学习C#,我遇到了以下代码 public class Album { public virtual int AlbumId { get; set; } public virtual int GenreId { get; set; } public virtual int ArtistId { get; set; } public virtual string Title { get; set; } public virtual decima
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
只是想知道下面的内容有什么不同?我的意思是,没有“获取和设置”,你也可以访问那些公共财产。是什么让这些东西变得重要
public class Album
{
public virtual int AlbumId;
public virtual int GenreId;
public virtual int ArtistId;
public virtual string Title;
public virtual decimal Price;
public virtual string AlbumArtUrl;
public virtual Genre Genre;
public virtual Artist Artist;
}
不能声明虚拟字段
控制对象私有字段值。例如,如果您不想允许整数为null或负值
bool started;
public bool Started
{
get { return started; }
set
{
started = value;
if (started)
OnStarted(EventArgs.Empty);
}
}
another example
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
set {
if (value < 0)
positiveNumber = 0;
else positiveNumber = value;
}
}
第一种情况是处理属性,第二种情况是处理字段 与使用属性相比,使用字段有几个缺点。这些缺点包括:
get
或set
中设置断点,但不能在访问字段时设置断点长话短说:始终使用公共属性,而不要使用公共字段。有许多不同之处:
- 属性由编译器转换为方法。因此,您可以将它们声明为虚拟的,并在派生类中重写它们
- 使用属性,您可以将逻辑放入getter或setter(过滤、验证等)
- 当您使用自动实现的属性(
)时,似乎您也可以只使用公共字段。但是,使用属性意味着您可以在以后更改getter或setter实现,而无需更改类公开的接口。如果您使用了一个字段,并且希望在读取该字段时实现过滤,则必须引入一个新方法,将该字段设置为私有字段,并断开该类型的所有现有使用者{get;set;}
{get;set}
访问器生成属性。因此,新手开发人员通常会得到具有大量属性的类,这些属性将类型的状态公开给世界。默认情况下,您至少应该使用{get;private set;}
。通过提供get(访问器)和set(mutator)方法,您可以控制访问和变异。
例如:
您有一个属性,不希望将其设置为任何大于15的值。因此,在set方法中设置必要的限制。除非使用set方法,否则无法控制
但是在您的示例中,get和set方法是默认的,意味着不控制任何内容。属性背后的主要原因是以受控的方式保护和显示私有数据 事实上,属性在使用中表现出如下能力:
public virtual int AlbumId
{
get { // ... some magical operations ... }
set { // ... some magical operations ... }
}
关于你的主要问题-本例中的区别是什么-主要关注点是virtual
关键字
此关键字导致属性可重写,因此任何其他代码都可以重写默认的get代码>方法。这意味着您拥有自己的默认行为,其他代码(在实体框架中非常常用)实现它们自己的逻辑
你例子中的第二个不是属性,所以它们不能表达这种神奇的能力 请参见“仅能访问类”属性没有用处。属性应该有一些值。Get and Set将设置值并获取值。谢谢各位,我将删除我的question@bluebill1049谢谢你的提问,我了解了很多东西,但是设置属性和直接使用classname.variablename等值有什么区别吗?@M.N.S.@M.N.S:从技术上讲,语法是一样的,但是在引擎盖下有一些不同。例如,在您的情况下(虚拟属性),您可以在派生类中重写它(请参见我的编辑)。不,不,不,只要忘记虚拟和所有,如果albumid等是在公共类中公开定义的,那么通过继承,我们也可以像classname.variablename一样直接访问它们。那么为什么要使用属性呢?任何特定的好处???通常我们使用属性来限制访问(例如,get是公共的,set是受保护的或私有的);对于复杂输出(get),例如,如果标题为null或空,则将AlbumId返回为0;用于验证(设置),例如,您可以在尝试将负值设置为AlbumId时引发异常;对于接口实现-您可以将属性放入接口(属性是一个方法),但不能放入字段;对于多态行为,您可以设置属性,但不能设置字段为VitualTanks,这是有意义的
public class GreatAlbum: Album {
private Boolean m_IsGreat;
public override int AlbumId {
get {
if (m_IsGreat)
return base.AlbumId
else
return 0;
}
set {
m_IsGreat = (value != 0);
base.AlbumId = value;
}
}
...
}
bool started;
public bool Started
{
get { return started; }
set
{
started = value;
if (started)
OnStarted(EventArgs.Empty);
}
}
another example
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
set {
if (value < 0)
positiveNumber = 0;
else positiveNumber = value;
}
}
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
}
public virtual int AlbumId
{
get { // ... some magical operations ... }
set { // ... some magical operations ... }
}