如何在c#中正确封装,使Main不能改变值
本文关键字:Main 不能 能改变 封装 | 更新日期: 2023-09-27 18:05:56
我有一个关于c#封装的看似简单的问题。
在我们的一次作业中,我们应该创建一个简单的二维坐标计算系统,并正确封装文件,这样我们就不能从Main方法中编辑点的位置或长度。
我创建了两个c#文件,即Line和Point。文件program。cs是给我们的,所以我们应该解决这个问题,我们不允许改变文件中的任何代码。我们应该封装的文件是Line.cs或Point.cs文件,这样Main方法就不能从那里编辑点的位置,例如写入p1.X = 0;
。下面是我到目前为止写的文件:
Program.cs
using System;
using coordinationSystem;
class Program
{
public static void Main()
{
Point p0 = new Point();
Point p1 = new Point(-10, -10);
Console.WriteLine("Point p0, position = (" + p0.X + ", " + p0.Y + ")");
Console.WriteLine("Point p1, position = (" + p1.X + ", " + p1.Y + ")");
Line theLine = new Line(p0, p1); //This is the correct line.
outdata("Print 1 of the line", theLine);
p1.X = 0; //This is the thing I'm trying to prevent...
outdata("Print 2 of the line", theLine);
Point startposition = theLine.Position();
startposition.Y = 5; //... same with this one
outdata("Print 3 of the line", theLine);
}
private static void outdata(string text, Line theLine)
{
double length = theLine.Length();
Point startPos = theLine.Position();
Console.WriteLine("'n" + text);
Console.WriteLine("==================================");
Console.WriteLine("Length = {0 :f4} units", length);
Console.WriteLine("Position = ({0},{1})", startPos.X, startPos.Y);
Console.WriteLine("----------------------------------");
}
}
Point.cs
namespace coordinationSystem
{
public class Point
{
private int x, y;
public Point() : this(0, 0) { } //Default-constructor.
public Point(int X, int Y) //Constructor.
{
this.X = X;
this.Y = Y;
}
public int X //Property for the X-coordinate.
{
get { return x; }
set
{
x = value;
}
}
public int Y //Property for the Y-coordinate.
{
get { return y; }
set
{
y = value;
}
}
}
}
Line.cs
using System;
namespace coordinationSystem
{
public class Line
{
private Point p0;
private Point p1;
public Line(Point p0, Point p1)
{
this.p0 = p0;
this.p1 = p1;
}
public double Length()
{
double pointLength = Math.Sqrt(Math.Pow(p0.X - p1.X, 2) + Math.Pow(p0.Y - p1.Y, 2));
return pointLength;
}
public Point Position()
{
return p0;
}
}
}
我得出的结论是,我可能应该使用get
和set
,但这并没有为我工作,因为Main中的theLine.Position();
是一个方法(正如我之前写的,我们不应该编辑Program.cs/Main)。
有什么想法吗?任何帮助将非常感激!
编辑:这是分配文本(从瑞典语粗略翻译):
考虑是否有可能破坏线路,如果你有访问对行和端点的引用。发生了什么?例如,如果您要更改Main中的p0或p1方法在创建行之后?当这条线发生了什么你在Main方法中移动起始位置吗?修改中的代码类线和点,以避免上述问题
这个问题有多种解决方案,这里有两个:
1-转换点到结构体。
结构是按值传递的,而不是按引用传递的,所以当你在方法上返回p0时,它将是一个副本,如果有人改变了返回点,原始行将保持不变。
2-复制点
不直接返回p0,只返回new Point(p0)。X, p . y),它将得到与1
相同的结果无论如何,试着让你的老师被解雇,她不懂c#,她只懂Java,因此她不理解属性是如何工作的,因为任何c#程序员都会使用属性而不是函数从更高的类(如Line)中检索属性。
编辑:如果你使用方法2,那么也克隆在Line: 的构造函数上使用的点 public Line(Point p0, Point p1)
{
this.p0 = new Point(p0.X, p0.Y);
this.p1 = new Point(p1.X, p0.Y);
}
由于无法更改Main()
中明显损坏的代码,因此基本上只有两个选项:
- 在
- 在
set
访问器中不做任何操作(也就是说,不实际更改值)。
set
访问器中抛出异常。它看起来像这样
public int X {
get {
return x;
}
set {
// do nothing
}
}
或:
public int X {
get {
return x;
}
set {
throw new Exception("Cannot change value of X");
}
}
对于Y和其他属性也可以这样做。
修改类中的代码Line和Point,使上述问题是避免。
为了避免从Main方法访问的问题,最好在编译时防止它,因此所需的修改如下:
使用private set
的属性:
public int X //Property for the X-coordinate.
{
get { return x; }
private set
{
x = value;
}
}
public int Y //Property for the Y-coordinate.
{
get { return y; }
private set
{
y = value;
}
}
使用与y属性相同。
公共类点{
public Point() : this(0, 0) { } //Default-constructor.
public Point(int X, int Y) //Constructor.
{
//this.X = X;
//this.Y = Y;
setx(X);
//this.y = Y;
}
public int X //Property for the X-coordinate.
{
get { return x; }
private set
{
x = value;
}
}
public int Y //Property for the Y-coordinate.
{
get { return y; }
}
public int setx(int Xvalue)
{
return x = Xvalue;
}
}