我将在编程中改变我的C#风格(我一直在使用'public static'代表变量,方法 - 一切)。
我的问题:
public class WinSock
{
public Socket sock;
public byte[] data;
.....
}
var data = new byte[2058];
data = WinSock.data;
或者这个:
private class WinSock
{
private Socket sock;
private byte[] data;
.....
public byte[] getdata()
{
get {return data;}
}
}
WinSock ws = new WinSock();
var data = new byte[2058];
data = ws.getdata();
在这两种情况下,都可以从其他类访问数据和sock变量。
两个声明中哪一个更好?
答案 0 :(得分:11)
通常,将字段公开并不是一个好主意。
由于getdata是一个属性,因此应该称为Data。
private class WinSock
{
private Socket sock;
private byte[] data;
.....
public byte[] Data
{
get { return data; }
}
}
公共接口由公共属性和方法组成,应确保状态(字段)永远不会出现矛盾。该班负责这些领域。它不应该允许任何人直接写入它。这就是封装的内容。
答案 1 :(得分:4)
从纯粹的“宣言”方面来说,第二个稍微好一点。但是,从设计角度(以及从可见的角度来看),这并不好。具体来说,返回对类中私有字段的数组的引用是一个很大的禁忌。考虑:
private class WinSock
{
private Socket sock;
private byte[] data;
.....
// Read at most length bytes of data to buffer starting at offset
// and return the number of bytes read
public int Read(byte[] buffer, int offset, int length)
{
// ...
}
}
WinSock ws = new WinSock();
var data = new byte[2058];
int bytesRead = ws.Read(data, 0, data.Length);
答案 2 :(得分:4)
第二个更接近通常被认为更好的东西。在面向对象编程中,我们将变量封装在类中,并且只在类外部尽可能少地公开。
使用首字母大写字母命名您的属性,并将其命名为数据成员而不是方法,即Data
而不是getdata
。
public class WinSock {
private Socket _socket;
private byte[] _data;
public Socket Socket {
get { return _socket; }
}
public byte[] Data {
get { return _data; }
}
}
(命名私有成员变量的一种方法是使用下划线。还有一些常用的惯例,但重要的是选择一个并坚持下去。)
在C#3中,还有一个属性的快捷语法:
public class WinSock {
public Socket Socket { get; private set; }
public byte[] Data { get; private set; }
}
答案 3 :(得分:3)
第二个。它被称为“封装”。您隐藏并保护您的数据不受外界影响。
答案 4 :(得分:3)
private
- 然后访问仅限于外部类。 internal
会更常见(并且是非嵌套类的默认值)public Socket sock;
)public Socket Socket {get; private set;}
)getdata
是一种方法还是一种财产;-p 答案 5 :(得分:1)
怎么样:
public Socket Sock { get; private set; }
public byte[] Date { get; private set; }
如果getter和setter不需要任何验证逻辑,则自动实现的属性是可行的方法。这提供了封装,并允许您稍后在需要时将实现更改为手动实现的属性,而不强制重新编译引用您的.dll。
答案 6 :(得分:0)
不要使用GetMethod(),而应将私有字段包装在属性中。
public class WinSock
{
private Socket sock;
private byte[] data;
public byte[] Data
{
get { return data; }
set { data = value; }
}
}
答案 7 :(得分:0)
我还要保证第二个代码位,修改后将字段包装到属性中并正确命名。因此,您可以将属性命名为“数据”而不是“getdata”。
答案 8 :(得分:0)
还有几点: