1

シンプルなテキストゲームを作成しています。私のCharacter構造体は値をリセットし続けCanます。私は何を間違っていますか、どうすれば修正できますか? コードは次のとおりです。

namespace MyNamespace
{
   struct Character
   {
      public float Can;
      //...
   }

   class MainClass
   {
      public static void Move (Character a)
      {
         bool cal = true;

         while (cal) 
         {
            Thread.Sleep(500);

            if(a.Can <= 100)
            {
               a.Can += 1;
            }
            else
            {
               cal = false;
            }
         }
     }
  }

  //...
}
4

6 に答える 6

2

Astruct値型です。メソッドに渡すか、別の変数に代入すると、データがコピーされます。次に、コピーを操作します。

メソッド call を検討してくださいDinlen (oyuncu);。文字をコピーし、コピーoyuncuのフィールドを変更します。Can

class代わりに参照型 ( ) の使用を検討してください。を使用する場合は、不変structにすることを検討してください。スレッドを読むなぜ変更可能な構造体が悪なのですか?

于 2013-02-18T15:48:57.797 に答える
0

前述のように、構造体は値型であり、コピーによって渡されます。あなたはこのようにrefによってそれを渡すことができます:

public static void Move (ref Character a)
{
...
}

そしてそれをこのように呼びます:

var a = new Character();
MainClass.Move(ref a);
于 2013-02-18T15:52:59.960 に答える
0

構造体の代わりにクラスを使用することを検討してください。

于 2013-02-18T15:48:35.443 に答える
0

構造体インスタンスをメソッドに渡すと、構造体のコピーが作成されます (値によって渡されます)。メソッド内の構造体を変更しても、渡した元の構造体には影響しません。

ソリューション?構造体の代わりにクラスを使用します。参照によって渡されるクラスのインスタンス。参照によって構造体を渡すことはできますが、なぜクラスのような構造体を使用しようとするのでしょうか? 代わりにクラスを使用してください。

class Karakter
{
    public string Isim { get; set; }
    public float Can { get; set; }
    public int Seviye { get; set; }
    public int Exp { get; set; }
    public float Guc { get; set; }
    public string Irk { get; set; }
    public int vExp { get; set; }

    public override string ToString()
    {
        return String.Format("Adınız:{0}\nIrkınız:{1}\nCan:{2}\nGuc:{3}", 
                             Isim, Irk, Can, Guc);
    }
}

ところで、.NET の値と参照型について読むと役に立つと思います。

于 2013-02-18T15:35:11.600 に答える
0

問題はstruct、変数として最初のメソッドに渡していることだと思いますが、構造体は値型です。つまり、参照渡しではなく、コピーされます。

に変更するstructclass、必要な動作が得られます。

PS を選んだ理由はありますstructか?これらは通常、開発者がこのタイプを使用する利点と欠点について詳しく知っている、より高度なシナリオで使用されます。

于 2013-02-18T15:36:32.523 に答える
0

メソッドに構造体を変更させる目的でメソッドに構造体を渡したい場合、メソッドrefはパラメーターで修飾子を使用する必要があります。refパラメータなしで構造体をメソッドに渡すと、メソッドがその構造体のフィールドを変更することはできません。

ref修飾子を使用する必要がないように、構造体をクラスに置き換えることを提案する人もいることに注意してください。変更可能なクラス オブジェクトへの参照を受け取るすべてのメソッドは、その後いつでも自由にオブジェクトを変更できるため、これは危険な概念です。変更可能なクラス オブジェクトへの参照を、受信者がそれを変更することを許可せずに渡す明確な方法はありません。任意の将来の時点でのオブジェクト。構造には、これらの問題のいずれもありません。

オブジェクトが type などの値型フィールドを保持している場合、MyBoundsIDrawing.Rectangleを呼び出すと、それが変更されるFoo(MyBounds)可能性がないことが保証されます。さらに、私が呼び出すと、変更される可能性があると予想できますが、メソッドが戻る前にすべての変更が完了します。変更可能なクラス型であった場合、調べなければ、将来任意の時点でのプロパティが変更される可能性があるかどうかを知る方法がありません。FooMyBoundsBar(ref MyBounds)BarMyBoundsRectangleFooBarMyBounds

構造体がクラスと異なることを理解していない人は、構造体の振る舞いに混乱するかもしれませんが、公開されたパブリック フィールドを持つすべての構造体は同じように振る舞います。構造体には、構造体で定義されたインスタンス メソッドとプロパティがパラメーターthisとして受け取るという悪い面がありrefますが、次のようなことをしようとすると、次のようになります。

readonly System.Drawing.Rectangle myRect = whatever;
...
myRect.Offset(4,2);

システムは をパラメーターmyRectとして渡すことができないことを認識しref(読み取り専用であるため)、診断を行わずにコードを次のように変更します。

readonly System.Drawing.Rectangle myRect = whatever;
...
System.Drawing.Rectangle temp = myRect;
temp.Offset(4,2);

ただし、ここで問題Rectangleなのは、変更可能であるという事実ではなく、任意のすべての値型メソッドを呼び出すときに、上記のコード置換が正当であるとコンパイラが想定しているという事実です。Microsoft が属性を追加して、読み取り専用構造体で特定のメソッドを呼び出すと、そのような置換を実行するのではなく、エラーが発生することを示すまでの間、構造体で動作する構造体メソッドをコード化する唯一の安全な方法は、"in- place" は次のような形式を使用することになります: static void Offset(ref Rectangle it, int x, int y);、その場合、本来のようRectangle.Offset(ref myRect, 4, 2);に失敗します。

于 2013-02-18T17:10:56.467 に答える