6

私は継承、ポリモーフィズム、カプセル化を広範囲に使用していますが、オブジェクトと変数のスコープに関する次の動作を知らなかったことに気付きました。違いは、次のコードで最もよく示されます。

public class Obj
{
    public string sss {get; set;}

    public Obj()
    {
        sss = "0";
    } 
}     

public partial class testScope : System.Web.UI.Page
 {
    protected void Page_Load(object sender, EventArgs e)
    { 
        Obj a = new Obj(); 
        String sss = "0";            
        Context.Response.Write(sss); // 0

        FlipString(sss);
        FlipString(a.sss);
        Context.Response.Write(sss + a.sss); // 0 0

        FlipObject(a);
        Context.Response.Write(a.sss); // 1
        Context.Response.End();
    }

    public void FlipString(string str)
    { str = "1"; }

    public void FlipObject(Obj str)
    { str.sss = "1"; }
}

したがって、変数がメソッドに渡されると、変更はメソッドのスコープに限定されると思いました。しかし、オブジェクトがメソッドに渡された場合、そのオブジェクトのプロパティが変更されると、メソッドを超えて拡張されるようです。

この動作が変数ではなくオブジェクトに対して存在するというルールである場合、これを受け入れることができますが、.netではすべてがオブジェクト、文字列です(例のようなものはSystem.Stringです)。メソッドに渡すパラメータのスコープ?

4

3 に答える 3

19

オブジェクトを引数として渡すことはありません。参照または値型の値のみを渡します。キーワードを使用しない限りref、引数は値で渡されます。つまり、パラメーターの初期値は引数の評価された値であり、パラメーターの値への変更は呼び出し元には表示されません。

ただし、パラメーターの値 (参照型の場合) は単なる参照であることを理解することは非常に重要です。参照が参照するオブジェクトの内容を変更すると、その変更呼び出し元に表示されます。

これは、数段落以上に値するトピックです。詳細については、.NET でのパラメーターの受け渡しに関する私の記事を読むことをお勧めします。

于 2009-03-08T20:20:57.447 に答える
1

クラス(あなたの場合は Obj )は参照型であるため、関数を呼び出すときに実際に行っているのは、このオブジェクトへの参照(基本的にこれをタイプセーフポインターと考えることができます)を渡すことです。変更可能なオブジェクト (つまり、クラス/参照型) への変更を防ぎたい場合は、適切な関数に渡す前にこのオブジェクトを複製する必要があります (または、値によってコピーされるように構造体にすることを検討してください)。

于 2009-03-08T20:23:01.480 に答える
1

.net の一部は「値」型であり、他は「参照」型であるため、値型の場合、メソッドにマーシャリングされると値が複製されますが、参照型には次のようなものがあります。明らかに親と同じスコープを共有するメソッドに渡されるポインタまたは参照。それで、私の質問は、何かが値型であるかどうかをどのように判断できるかです.intのような構造体はすべて値型ですが、文字列はオブジェクトSystem.Stringであっても構造体のように動作するように見えますか?

于 2009-03-08T20:20:40.567 に答える