吸气剂,固体剂和性质最佳实践。 Java与C#
我现在正在参加一个C#课程,我正试图找出最好的方法。我来自Java背景,所以我只熟悉Java最佳实践;我是C#新手!吸气剂,固体剂和性质最佳实践。 Java与C#
在Java中,如果我有私人财产,我这样做;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
在C#中,我发现有很多方法可以做到这一点。
我能做到像Java:
private string name;
public void setName(string name) {
this.name = name;
}
public string getName() {
return this.name;
}
或者,我可以这样来做:
private string name;
public string Name {
get { return name; }
set { name = value; }
}
或者:
public string Name { get; set; }
哪一个我应该使用,以及什么每种方法都包含哪些警告或微妙之处?在创建类时,我遵循从Java中知道的一般最佳实践(尤其是阅读Effective Java)。例如,我赞成不变性(只在需要时才提供给定员)。我只是很好奇,看看这些实践如何适应用C#提供setter和getter的各种方式;从本质上讲,我如何将Java世界的最佳实践转化为C#?
编辑
我张贴此为乔恩斯基特的答案评论,但随后得到了久:
怎么样一个不平凡的性质(即具有显著处理和验证也许)?我仍然可以通过公开财产揭露它,但逻辑封装在get
和set
?为什么会/应该通过专用的setter和getter方法(以及相关的处理和验证逻辑)来做到这一点。
前C#6
我用最后的这些,对于一个微不足道的财产。请注意,我会称这是一个public属性,因为getter和setter都是公共的。
不变性对于自动实现的属性有点痛苦 - 你不能写一个只有吸气剂的自动属性;你能来最接近的是:
public string Foo { get; private set; }
这是不是真的不可改变 ...只是一成不变的类的外部。所以,你可能希望使用真正只读属性,而不是:
private readonly string foo;
public string Foo { get { return foo; } }
你肯定不想写getName()
和setName()
。在一些情况下,编写Get/Set方法而不是使用属性是有意义的,特别是如果它们可能是昂贵的并且您希望强调这一点。然而,你会想遵循PascalCase的.NET命名约定来处理方法,并且你不希望这样的普通属性用普通的方法来实现 - 这里的属性更加地道。
C#6
万岁,我们终于等来了合适的只读自动实现的属性:
// This can only be assigned to within the constructor
public string Foo { get; }
同样为只读属性,其做需要做一些工作,你可以使用成员身份属性:
public double Area => height * width;
无论您在C#中选择哪种方式,最终结果都是一样的。你将得到一个带有独立getter和setter方法的backinng变量。通过使用属性,您正在遵循最佳实践,所以这是您想要得到多么冗长的问题。
就我个人而言,我会选择自动属性,最后一个版本:public string Name { get; set; }
,因为它们占用最少的空间。如果您需要添加验证等功能,您可以随时扩展这些功能。
在C#中使用属性,没有获取/设置方法。他们在那里为您提供方便,而且是惯用的。
至于你的两个C#示例,其中一个就是另一个的语法糖。如果你需要的只是一个简单的实例变量包装,那么使用auto属性,当你需要在getter和/或setter中添加逻辑时,使用完整版本。
只要有可能,我宁愿公开string Name { get; set; }
,因为它简洁易读。然而,有时候这个是必要的
private string name;
public string Name {
get { return name; }
set { name = value; }
}
在C#支持暴露私人领域获取和/或设置的属性。你提到的thie表单是一个autoproperty,get和set会为你自动生成一个隐藏的pivot pivot字段。
我喜欢自动属性,但是你不应该在C#中执行set/get方法对。
public string Name { get; set; }
这简直就是auto-implemented property,在技术上与普通属性相同。编译时会创建一个后台字段。
所有属性最终都转换为函数,所以最终的实际编译实现与您在Java中使用的相同。
当您不必在后台字段上执行特定操作时,使用自动实现的属性。否则使用普通财产。当操作有副作用或计算成本高时使用get和set函数,否则使用属性。
如前所述,所有这些方法都会产生相同的结果。最重要的是你选择一个会议并坚持下去。我更喜欢使用最后两个属性的例子。
在C#中,首选方法是通过属性而不是getX()
和setX()
方法。此外,请注意,C#不要求属性同时具有get和set - 您可以拥有只读属性和只设置属性。
public boolean MyProperty
{
get { return something; }
}
public boolean MyProperty
{
set { this.something = value; }
}
首先让我试着解释一下你写的:
// private member -- not a property
private string name;
/// public method -- not a property
public void setName(string name) {
this.name = name;
}
/// public method -- not a property
public string getName() {
return this.name;
}
// yes it is property structure before .Net 3.0
private string name;
public string Name {
get { return name; }
set { name = value; }
}
这种结构也采用了时下但如果你想要做一些额外的功能,例如当一个价值在于它是最合适的设置你可以解析大写它,并将其保存在私人成员内部以供更改内部使用。
使用.NET框架3.0
// this style is introduced, which is more common, and suppose to be best
public string Name { get; set; }
//You can more customize it
public string Name
{
get;
private set; // means value could be set internally, and accessed through out
}
祝你更好的运气,在C#
如果你需要的是存储一些数据的变量:
public string Name { get; set; }
想使它看起来只读?
public string Name { get; private set; }
甚至更好...
private readonly string _name;
...
public string Name { get { return _name; } }
想要做一些价值分配属性之前检查?
public string Name
{
get { return m_name; }
set
{
if (value == null)
throw new ArgumentNullException("value");
m_name = value;
}
}
一般来说,GetXyz()和SetXyz()在某些情况下只使用,你只需要使用你的时候感觉对上消化道。一般来说,我会说我期望大多数get/set属性不包含很多逻辑,并且只有很少的(如果有的话)意想不到的副作用。如果读取属性值需要调用服务或从用户获取输入以构建我请求的对象,那么我会将其包装到一个方法中,并将其称为BuildXyz()
而不是GetXyz()
。
像这里的大多数答案一样,使用自动属性。直观,少量的代码,它更干净。如果您应该序列化您的课程,请标记课程[Serializable]
/[DataConract]
属性。如果你正在使用[DataContract]
马克成员与
[DataMember(Name="aMoreFriendlyName")]
public string Name { get; set; }
私人或公共setter方法取决于您的喜好。
另请注意,自动属性需要获取者和设置者(公有或私有)。
/*this is invalid*/
public string Name
{
get;
/* setter omitted to prove the point*/
}
或者,如果你只是想获得/集,创建一个支持字段自己
更确切的:任何代码reiew会指出,Java的方式是绕过有效的langauge和运行一个黑客(!)构造并终止属性的使用作为proeprty(即object.property =“value”)。在一些团队中,这会引发一场关于态度的良好谈话 - 取决于资历和激励,以便将这种态度用于竞争对手。严重的是,不要打仗LANGAUGE。特别是因为java的“方式”是为了不修改不动产支持的语言而选择的黑客。 – TomTom 2011-02-09 18:24:10
我想好消息是我的回答似乎与您提到的任何内容都不矛盾。坏消息是你的手指比我的快得多。伟大的洞察力,并感谢增加的细节。 – jeremyalan 2011-02-09 18:37:25
要回答你的编辑:你可以使用get/set方法以及你想要的任意数量的逻辑。我们经常这样做,特别是对于验证。但是,最佳实践并不是在属性中包含很多缓慢的逻辑(例如数据库访问),危险逻辑(异常抛出)或突变(更改很多状态)。预计财产或多或少会像一个简单的状态。更多的东西应该用一个函数来表示。 – CodexArcanum 2011-02-09 20:38:23