当我写一个类时,我总是通过这样的公共属性公开私有字段:
private int _MyField;
public int MyField
{ get{return _MyField; }
什么时候可以公开这样的公共字段:
public int MyField;
我正在创建一个名为Result的结构,我的意图是这样做:
public Result(bool result, string message)
{
Result = result;
Message = message;
}
public readonly int Result;
public readonly int Message;
最佳做法是什么?这样做好吗?
答案 0 :(得分:31)
我只会在公共字段是(静态)常量时公开它们 - 甚至那时我通常会使用属性。
“常量”是指任何只读,不可变的值,而不仅仅是可以在C#中表示为“const”的值。
即使是只读实例变量(如Result和Message)也应该封装在我视图的属性中。
有关详细信息,请参阅this article。
答案 1 :(得分:17)
使用公共字段的最佳做法是什么?
“不要。”另请参阅: Should protected attributes always be banned?涉及受保护的领域,但对于公共领域更是如此。
答案 2 :(得分:9)
使用属性。现在,C#很容易Automatic Properties!
答案 3 :(得分:4)
最佳做法是出于多种原因使用属性。首先,它将API与底层数据结构分离。其次,框架中绑定到对象的任何内容都会对属性产生影响,而不是字段。
我确信还有更多理由,但这两个似乎对我来说似乎已经足够了。
答案 4 :(得分:3)
我认为最佳做法不是这样做。除非你有必须直接访问该字段的某些极端性能需求,否则不要这样做。
这是一篇很好的文章:
http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx
答案 5 :(得分:2)
我建议使用类似的东西:
public class Result{
public bool Result { get; protected set; }
public string Message { get; protected set; }
public Result(bool result, string message) {
Result = result;
Message = message;
}
}
这样,你不需要声明成员变量,让编译器为你工作!代码非常简洁,重构也很简单。
答案 6 :(得分:2)
在C风格的语言(如C#)中,您应该通过属性公开字段。这也适用于VB.NET和其他.NET语言,以及它们共享相同的底层引擎。这样做的主要原因是
作为整数的公共MyField不公共属性MyField作为整数,它们在.NET下的所有情况下都没有相同的行为。
但是你可能会看到很多人继续公开领域。其中一些是由于VB6如何处理COM。在VB6中,Public MyField as Integer等同于Public Property MyField as Integer。因为当两者都被翻译成COM类型库时,它们都以相同的方式实现。
这导致了VB6对公共领域的许多奇怪限制。不在.NET和许多其他面向对象语言中的限制。这些限制是在编译时捕获的,因此可以防止程序员在脚下射击。如果你的课程在VB6中是私人的,那么这些限制中的一些,但不是全部,都得到了缓解。一般规则是您只能将类和数据类型公开为公共字段。
VB6的遗产意味着有很多程序员不知道.NET存在差异。
因为.NET在这方面没有帮助我们,所以你需要采取传统步骤,确保所有字段都通过属性公开。再次,因为在.NET中,字段与属性不同。
这个article(由其他人指出)解释了它的.NET方面。
答案 7 :(得分:1)
答案 8 :(得分:1)
我想以你的方式回答你的问题。
Readonly不是在公共字段上只有get访问器的方法。我主要在私有字段上使用readonly,我的私有字段只能从构造函数设置。所以要理解一个readonly字段只能在一个构造函数中设置,然后你只能访问它。
最佳做法是始终使用“属性”在构造函数后访问您的字段。所以,如果您必须从课堂内访问您的房产,我会提出:
private readonly int result;
private readonly int message;
public Result(bool result, string message)
{
this.result = result;
this.message = message;
}
public int Result
{
get{ return result; }
private set { result = value; }
}
public int Message
{
get{ return message; }
private set { message = value; }
}
这样你只能读取结果和消息,并且仍然可以从类内部写入。
如果您使用继承,可以根据需要设置保护集。
编辑:在根据问题中给出的内容阅读我做的代码之后,有一些错误,类名结果可能会抛出属性结果的错误,也就是我们的事实正在接收一个bool作为结果和一个字符串作为构造函数中的消息,但尝试将它们发送到int这将肯定不起作用。但是,对于它的价值来说,这是一种逻辑:
private readonly bool result;
private readonly string message;
public Answer(bool result, string message)
{
this.result = result;
this.message = message;
}
public bool Result
{
get{ return result; }
private set { result = value; }
}
public string Message
{
get{ return message; }
private set { message = value; }
}
答案 9 :(得分:0)
我给出的答案是,属性对Refactor更友好。
如果您有一个只读字段的程序集,则将它们更改为属性。如果你有另一个我访问字段(现在属性)的程序集,它们将无法在没有编译的情况下工作。 就编译器而言,字段和属性并不相同。
回到重构,说你从一个属性开始。现在您需要更改数据的来源(您将从另一个类访问它)。如果您正在处理字段,那么您就如何实现这一点做出了一些艰难的决定。属性更宽容 - 因为你可以在其中隐藏逻辑。
答案 10 :(得分:0)
通常,如果某个类型将用作数据持有者,则它应该是:
如果没有使用可变类的实际替代方法,是否公开公共字段的问题取决于是否有任何可预见的类需要在属性设置器中包含验证逻辑,以及是否类型成员的值将是值类型或类类型。如果Bounds
是Rectangle
类型的公共字段,则SomeClass.Bounds.Width
这样的表达式可以访问矩形的Width
,而无需访问任何其他成员。相反,如果Bounds
是属性 - 即使是可变属性 - 该表达式必须将Bounds
的所有四个成员复制到临时结构,然后访问Width
字段那个。