我想知道C#自动实现的属性public static T Prop { get; set; }是否是线程安全的.谢谢!
C#具有自动属性,可以大大简化您的代码:
public string Name { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
Run Code Online (Sandbox Code Playgroud)
Java有你写这么多代码:
private String name;
private String middleName;
private String LastName;
public String Name(){
return this.name;
}
etc..
Run Code Online (Sandbox Code Playgroud)
有没有特殊原因Java没有实现这样的东西?
我有以下代码类:
public class Foo
{
public Nested Bar { get; } = new Nested(this);
public class Nested
{
public Nested(Foo foo)
{
foo.DoSomething();
}
}
private void DoSomething()
{
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到此编译错误:
关键字'this'在当前上下文中不可用
我可以通过简单地不使用自动属性初始化器来修复它,并明确地将其移动到构造函数中:
public Nested Bar { get; }
public Foo()
{
this.Bar = new Nested(this);
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?是不是Auto-Property Initializer实际上转换为IL中的构造函数代码?
由于3.0 C#具有很好的语法糖,如自动属性,这大大简化了封装原理的实现.如果你将它与原子值一起使用,这是很好的,所以你可以像这样替换封装模式:
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
Run Code Online (Sandbox Code Playgroud)
只有一行:
public string FirstName { get; set; }
Run Code Online (Sandbox Code Playgroud)
我非常喜欢这个很棒的功能,因为它节省了很多开发人员的时间.
但是当你创建指向集合的属性时,事情并不是那么好.通常我会看到以两种方式之一实现的集合属性.
1)根本没有自动属性可以使用字段初始化程序:
private List<string> _names = new List<string>();
public List<string> Names
{
get { return _names; }
}
Run Code Online (Sandbox Code Playgroud)
2)使用自动属性.如果类只有一个构造函数,这种方法就可以了:
public List<string> Names { get; private set; }
public .ctor()
{
Names = new List<string>();
}
Run Code Online (Sandbox Code Playgroud)
但是当你以这样的方式处理像列表这样的可变集合时,你会破坏封装,因为这个属性的用户可以修改集合而不让容器知道(如果忘记将setter设为私有,甚至可以替换集合).
至于我,关于Encapsulate Collection模式,集合封装的正确实现应如下所示:
private readonly List<string> _names = new List<string>();
public ICollection<string> Names
{
get …Run Code Online (Sandbox Code Playgroud) 我有以下自动属性
[DefaultValue(true)]
public bool RetrieveAllInfo { get; set; }
Run Code Online (Sandbox Code Playgroud)
当我尝试在代码中使用它时我发现默认的false假设是因为我认为这是bool变量的默认值,有没有人知道什么是错的!?
我想使用自动实现的属性,但同时我想在每次更改属性时调用方法.
public float inverseMass
{
get;
set
{
onMassChanged();
inverseMass = value;
}
}
Run Code Online (Sandbox Code Playgroud)
先前的代码是否对属性进行了递归调用?如果是的话,如何实现呢?
我有一个目前自动的财产.
public string MyProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)
但是,我现在需要它在每次更改时执行一些操作,所以我想为setter添加逻辑.所以我想做一些事情:
public string MyProperty {
get;
set { PerformSomeAction(); }
}
Run Code Online (Sandbox Code Playgroud)
但是,这不构建...... MyProperty.get' must declare a body because it is not marked abstract, extern, or partial
我不能只让getter返回,MyProperty因为它会导致无限循环.
有没有办法做到这一点,还是我必须声明一个私有变量来引用?我宁愿不要MyProperty在这个类和它之外的代码中使用它
这可能听起来很幼稚,但......
class Widget
{
public int Foo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这很酷,并且使用支持字段来节省一些样板,但在那时,它不等同于简单:
class Widget
{
public int Foo;
}
Run Code Online (Sandbox Code Playgroud)
看起来它只不过是一个公共领域,尽管我认为它看起来与众不同.但是,从设计的角度来看,如果不利用封装,使用属性有什么好处?
我同意马克·西曼的观点,即自动属性在某种程度上是邪恶的,因为它们打破了封装.但是,我确实喜欢它们带来的简洁语法,可读性和便利性.
我引用:
public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)
代码片段的问题并不在于它包含太多的仪式.问题是它破坏了封装.事实上
"[...] getter和setter没有实现封装或信息隐藏:它们是一种语言合法化的方式来违反它们."
James O. Coplien和GertrudBjørnvig.精益建筑.威利.2010. p.134.
大多数情况下,添加一个非null保护子句对于属性设置器来说已经足够了,我想知道是否有比下面的更好的方法.更好的是,我的意思是更简洁/更少重复.
使用代码合同:
private string _username;
public virtual string Username
{
get { return _username; }
set
{
Contract.Requires(value != null);
_username = value;
}
}
Run Code Online (Sandbox Code Playgroud)
使用vanilla .NET:
private string _username;
public virtual string Username
{
get { return _username; }
set
{
if (value == null) throw new ArgumentNullException("Username");
_username = value;
}
}
Run Code Online (Sandbox Code Playgroud) c# ×9
properties ×3
.net ×1
.net-4.0 ×1
attributes ×1
c#-3.0 ×1
constructor ×1
guard-clause ×1
history ×1
java ×1
oop ×1
static ×1
vb.net ×1