在C#中,是什么使字段与属性不同?何时应该使用字段而不是属性?
当前回答
我将举几个使用财产的示例,这些属性可能会使齿轮转动:
惰性初始化:如果您有一个对象的属性,该属性的加载成本很高,但在正常运行代码时无法访问,则可以通过该属性延迟加载。这样,它就只是坐在那里,但当另一个模块第一次尝试调用该属性时,它会检查基础字段是否为空-如果为空,它会继续加载它,调用模块不知道。这可以大大加快对象初始化。肮脏追踪:这是我从StackOverflow上的问题中了解到的。当我有很多对象的值可能在运行期间发生了变化时,我可以使用该属性来跟踪它们是否需要保存回数据库。如果对象的任何一个属性都没有改变,IsDirty标志都不会被触发,因此保存功能在决定需要返回数据库时会跳过它。
其他回答
财产显示字段。字段应该(几乎总是)对类保持私有,并通过get和set财产进行访问。财产提供了一个抽象级别,允许您更改字段,同时不影响使用类的事物访问字段的外部方式。
public class MyClass
{
// this is a field. It is private to your class and stores the actual data.
private string _myField;
// this is a property. When accessed it uses the underlying field,
// but only exposes the contract, which will not be affected by the underlying field
public string MyProperty
{
get
{
return _myField;
}
set
{
_myField = value;
}
}
// This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
// used to generate a private field for you
public int AnotherProperty { get; set; }
}
@Kent指出,财产不需要封装字段,它们可以对其他字段进行计算,也可以用于其他目的。
@GSS指出,您还可以在访问属性时执行其他逻辑,例如验证,这是另一个有用的功能。
这里清楚地解释了区别。然而,只是为了总结和强调:
字段封装在类内部以进行内部操作,而财产可用于将类公开给外部世界,以及共享链接中显示的其他内部操作。此外,如果您希望基于特定字段的值加载某些方法或用户控件,则属性将为您完成此操作:
例如:
您可以在asp.net页面中的用户控件下方运行,只需为aspx页面中控件的Id前缀赋值,如下所示:
useMeId.Id=5 ---call the property of user control "UseMe.ascx"
使用Me.ascx
<%@ Register Src=~/"UseMe.ascx" TagPrefix="uc" TagName="UseMe" %>
<uc:UseMe runat="Server" id="useMeId" />
UseMe.ascx.cs
private int currentId;
public int Id
{
get
{
return currentId;
}
set
{
currentId = value;
LoadInitialData(currentId);
}
}
Private void LoadinitialData(int currentIdParam)
{
//your action
}
此外,财产允许您在设置值时使用逻辑。
因此,如果值大于x,您可以说只想将值设置为整数字段,否则将引发异常。
非常有用的功能。
财产封装字段,从而使您能够对要设置或检索的值执行附加处理。如果您不需要对字段值进行任何预处理或后处理,那么使用财产通常是过分的。
看完所有答案后,我没有找到关于并发访问的答案。
假设您有一个可以异步访问的API端点,并且您使用静态字段存储数据,并且需要对静态字段进行独占访问。
为了重现这个示例,您需要一个负载测试来同时访问端点。
当使用静态int计数器字段时,端点在两次或多次访问中获得相同的值。
当使用静态int计数器属性时,端点处理并发性,并始终获取计数器的新值。
这根本不能回答问题,但在使用其中一种或另一种时,必须考虑到这种行为。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何创建类属性?
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何转换列表<字符串>列表<int>?