2016-09-05 3 views
0

C#でのカプセル化に関する一見単純な質問があります。C#で正しくカプセル化する方法Mainでは値を変更できません

私たちの学校の課題の1つでは、単純な2次元座標計算システムを作成し、ファイルを正しくカプセル化して、メインメソッドからポイントの位置や長さを編集することはできません。

私は2つのC#ファイル、すなわちラインとポイントを作成しました。 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("----------------------------------"); 
    } 
} 

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; 
     } 
    } 
} 
Point.cs: 以下は、私がこれまで書いてきたファイルをしています

私はおそらくgetsetを使用すべきだという結論に達しましたが、MainのtheLine.Position();がメソッドであるため(これは私が以前に書いたように、プログラムを編集するはずがないため) cs/Main)を実行します。

ここにアイデアはありますか?どんな助けでも大歓迎です!

EDIT:

これは(緩くスウェーデン語から翻訳)割り当てテキストです:Mainメソッドからのアクセスの問題を回避するために

Consider whether it is possible to sabotage the line if you have access to references to the lines both endpoints. What happens, for example, with the line if you would change the p0 or p1 in the Main method after you have created the line? What happens to the line when you move the starting position in the Main method? Modify the code in the class Line and Point so that the above problems are avoided.

+0

「メイン」を変更するつもりがない場合は、どのようにして 'p1.X = 0'を「防止する」ことを望みますか?あなたはそれをコンパイルしたくない、あるいは他の何かをしたいですか? (Btw、今は自動的に実装されたプロパティについて学ぶ良い時間です...) –

+0

あなたがLine.csではなくPoint.csにアクセスするとコメントした行。 – Florian

+0

あなたはそうかもしれませんが、Line.csとPoint.csの両方を編集できるように変更する必要があります。私の悪い。 – tobulos1

答えて

2

さて、その問題は、複数のソリューションを持っているが、2つです:

構造体へのポイントを1-変換します。

構造体は参照によってではなく値によってパージされます。したがって、メソッドでp0を返すとコピーされます。返された点が変更された場合、元の行は変更されません。

2 - ポイントを複製します。代わりに、直接、ちょうど新しいポイント(P0.X、p0.Y)を返しP0を返す

、それは彼女が知っていない、あなたの教師が解雇取得しようと、とにかく1

と同じ結果になりますC#では、Javaを知っているので、C#プログラマーがプロパティを使用し、Lineなどの上位クラスからプロパティを取得する関数ではなく、プロパティの仕組みを理解していません。

EDIT:あなたはメソッド2を使用する場合は、その後もラインのコンストラクタで使用されるポイントのクローンを作成します。yプロパティと同じ

public Line(Point p0, Point p1) 
    { 
     this.p0 = new Point(p0.X, p0.Y); 
     this.p1 = new Point(p1.X, p0.Y); 
    } 
+0

まあ、正確にPositionメソッドを返しました。 'public Punkt Position() { return new Punkt(p0.X、p0.Y); } ' しかし、今では、メインmetodの' p1.X = 0; 'が計算を変更しないことを確認するだけです!ありがとう! – tobulos1

+0

お待ちください、私は更新プログラムを作成する必要があります。 – Gusman

+0

ありがとう!これはそれでした。これでMainメソッドは 'p1.X = 0;'や 'startposition.Y = 5;'があっても行の計算を変更しません。 – tobulos1

2

Modify the code in the class Line and Point so that the above problems are avoided.

、それはコンパイル時に、それを防ぐために最善であります時間がかかるので、希望する変更は次のようになります。

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; 
    } 
} 
+0

これはうまくいかず、Mainメソッドは 'p1.X = 0;'や 'startposition.Y = 5;'のプロパティに到達できないようです。 。 – tobulos1

+2

それはあなたが望むものではありませんか?メインメソッドが値を変更するのを防ぐ –

+0

変更が試行された場合に例外をスローすることができますが、正に、それはちょうどひどいプログラミングです。私はこの宿題の割り当てについてはあまりよく分かりません... – siride

2

あなたはMain()で明らかに壊れたコードを変更することはできませんので、あなたは基本的に2つの選択肢が残されています。:setアクセサで

  1. スロー例外プロパティの

    使用private set

  2. 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及び他の特性のために同じことをするだろう。ここ

+0

しかし、彼が他のクラスからセッターにアクセスしたいのであればどうでしょうか?もしsetterが常に例外をスローすれば、setterを持つ点は何でしょうか? –

+1

これは間違いありませんが、これは間違いありません。しかし、ねえ、割り当ては奇妙です(それはクラスがお互いに戦っているようです)。 – Andrew

+0

@UmairM:私は同意しますが、IMHOは非常に悪い宿題です。 PointクラスとLineクラスを変更できないようにするコードをコンパイルする唯一の方法は、セッターが実際に値を変更しないようにすることです。 – siride

0

使用。

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; 
     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; 
    } 
} 
関連する問題