吸气剂,制剂和性质的最佳实践。 Java与C#

我现在正在参加一个C#课程,我正试图找出最好的做法。 我来自Java背景,所以我只熟悉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; } 

我应该使用哪一个,每个方法涉及的警告或微妙之处是什么? 创build类时,我遵循我从Java所了解的一般最佳实践(特别是阅读Effective Java)。 因此,例如,我赞成不变性(只在需要时才提供setter)。 我只是好奇,看看这些做法是如何适应在C#中提供setter和getter的各种方法; 从本质上讲,我将如何将Java世界的最佳实践转化为C#?

编辑

我发布这个作为评论Jon Skeet的答案,但后来很长:

怎么样一个非平凡的财产(即可能有重要的处理和validation)? 我仍然可以通过一个公共属性公开,但与逻辑封装getset ? 为什么会/应该通过专用的setter和getter方法(以及相关的处理和validation逻辑)来做到这一点。

Pre-C#6

我会用最后一个,为一个微不足道的属性。 请注意,由于获取者和设置者都是公共的,因此我将这称为公共属性。

自动实现的属性对不可变性是一个痛苦 – 你不能写一个只有一个getter的自动属性; 你可以最近的是:

 public string Foo { get; private set; } 

这不是真正的不可变的……只是在你的class级以外不变。 所以你可能希望使用一个真正的只读属性:

 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; 

如果你只需要一个variables来存储一些数据:

 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属性不包含很多逻辑,并且有很less的,如果有的话,意想不到的副作用。 如果读取属性值需要调用一个服务或从用户那里获取input以构build我请求的对象,那么我会将它包装到一个方法中,并将其称为BuildXyz()而不是GetXyz()

在C#中使用属性,而不是get / set方法。 他们在那里是为了您的方便,而且是惯用的。

至于你的两个C#的例子,其中一个就是简单的语法糖。 如果你所需要的只是一个简单的实例variables包装,那么使用auto属性,当你需要在getter和/或setter中添加逻辑时,使用完整版本。

无论您在C#中select哪种方式,最终结果都是一样的。 你将得到一个backinngvariables与单独的getter和setter方法。 通过使用属性,您正在遵循最佳实践,所以这是您想要得到多么冗长的问题。

我个人会select自动属性,最后的版本: public string Name { get; set; } public string Name { get; set; } public string Name { get; set; } ,因为它占用的空间最less。 如果您需要添加validation等function,您可以随时扩展这些function。

在C#支持暴露私人领域获取和/或设置的属性。 你提到的thie表单是一个autoproperty,get和set会为你自动生成一个隐藏的pivot pivot字段。

如果可能,我倾向于使用自动属性,但是不应该在C#中使用set / get方法对。

 public string Name { get; set; } 

这只是一个自动实现的属性 ,在技术上与普通属性相同。 编译时会创build一个后台字段。

所有的属性最终都被转换为函数,所以最终的实际编译的实现和你在Java中使用的一样。

如果不需要对后台字段执行特定的操作,请使用自动实现的属性。 否则使用普通财产。 当操作有副作用或计算成本高时使用get和set函数,否则使用属性。

只要有可能,我宁愿公共string Name { get; set; } string Name { get; set; } 因为它简洁易读。 但是,有时候这个是必要的

 private string name; public string Name { get { return name; } set { name = value; } } 

如前所述,所有这些方法都会产生相同的结果。 最重要的是,你select一个惯例,坚持下去。 我更喜欢使用最后两个属性的例子。

在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; } } 

现在也使用这个结构,但是如果你想要做一些额外的function,比如当你设置一个值,你可以parsing它并将其保存在私有成员中以供内部使用。

使用.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#

像这里的大多数答案一样,使用自动属性。 直观,less量的代码,它更干净。 如果您要序列化您的类,请使用[DataConract]属性标记类[Serializable] /。 如果您正在使用[DataContract]标记该成员

 [DataMember(Name="aMoreFriendlyName")] public string Name { get; set; } 

私人或公共二传手取决于你的喜好。

另请注意,自动属性需要获取者和设置者(公有或私有)。

 /*this is invalid*/ public string Name { get; /* setter omitted to prove the point*/ } 

另外,如果你只想获得/设置,你自己创build一个支持领域