2012-03-15 9 views
14

C#のデフォルトはByValです。同じ変数名を多くの場所で使用し、渡された値が変更されて戻ってきたことに気付きました。私はC#のスコープメカニズムが間違っていると思っています。ここでは公開ライセンスはローカルライセンスの値を上書きします。私は紛争で変数名の名前を簡単に変更できることを知っていますが、範囲についての事実を学びたいと思います。C#デフォルトで引数を渡すのは、ByValの代わりにByRefです。

public static class LicenseWorks 
    { 
    public static void InsertLicense(License license) 
    { 
     license.registered = true; 
     UpdateLicense(license); 
    } 
    } 

    public partial class formMain : Form 
    { 
    License license; 

    private void btnPay_Click(object sender, EventArgs e) 
    { 
      license.registered = false; 
      LicenseWorks.InsertLicense(license); 

      bool registered = license.registered; //Returns true! 
     } 
    }  

アップデート:私は解決策として以下を追加しました:

public static void InsertLicense(License license) 
    { 

     license = license.Clone(); 
     ... 
    } 

答えて

51

引数は値渡しされている - しかし、引数がオブジェクトではない、それは参照です 。その参照は値渡しされていますが、その参照を介してオブジェクトに加えられた変更は依然として呼び出し元に表示されます。あなたがInsertLicense(ref foo)を呼び出す場合

public static void InsertLicense(ref License license) 
{ 
    // Change to the parameter itself, not the object it refers to! 
    license = null; 
} 

さて、それは後でfooヌルを行います:

これはへの変更パラメータ自体このようなを参照することによりリアルパス、と非常に異なっています。参考文献がなければ、そうではないでしょう。私が書いた

詳細については

、参照2記事:

  • Parameter passing in C#
  • References and values

      あなたは違いを学ぶ必要が
  • +0

    OKこれは重複していると思いました。 –

    3

    (値型と参照型との違い) 参照タイプおよび値タイプ。ここで私はあなたが実際にリファレンスを問題のインスタンスに解析しているという意味で、参照タイプのライセンスを使用していると推測します。必ずしも値型は、しばしばスタックまたは参照型内に割り当てられる修正しない、がhttp://msdn.microsoft.com/en-us/library/aa711899(v=vs.71).aspx

    参照。参照型は常にマネージヒープに割り当てられますが、

    +0

    ハ!もちろん、ジョン・スケートは私をパンチに倒した。 – nietras

    +0

    参照「ポインタ」を呼び出さないでください。彼らはまったく違う動物です! –

    +0

    私は知っていますが、ここでのポイントを説明するために、私はそれが最も明確であると思っていました。それが引用符で囲まれている理由です。 – nietras

    1

    InsertLicenseでライセンスを渡すときは、値ではなく参照として渡します。 つまり、登録された項目をtrueに変更すると、それが変更され、参照を返した後に登録された項目がtrueになります。

    1

    あなたは値でライセンス引数を渡しています。基本的には、オブジェクトのパブリックプロパティを変更することができます。しかし、あなたはしなかった場合、すなわち、新しいオブジェクトにライセンスオブジェクトの参照を再割り当てする場合は、この:

    public static void InsertLicense(License license)  
    {   
        license = new Licence();   
        UpdateLicense(license);  
    } 
    

    あなたが参照によってそれを通過しない限り、静的メソッドで定義された新しいライセンスオブジェクトを参照しないだろう、発信者。

    refまたはoutキーワードを使用しない限り、すべてのパラメータは値によってメソッドに渡されることに注意してください。

    0

    は、この全体に蘭と私はMicrosoftが言っていることを共有すべきであると思った:。

    は、「参照型の概念と参照渡しの概念を混同しないでください二つの概念が同じではないメソッドのパラメータは、することができます。それが値型であるか参照型であるかにかかわらず、refによって変更されます。参照渡し時に値型のボクシングはありません。

    MSDN: ref (C# Reference)

    関連する問題