2017-10-03 10 views
-1

クラスはメソッドから名前を設定することができ、それが値を保つ:例クラスでrefを追加する必要がないのはなぜですか?

Employeer e = new Employeer() 
SetName(e); 

しかし、我々は、コールメソッドSetNameメソッド(e)の しかし、あなたはREF

を追加する必要があり、文字列参照を追加する必要はありません
string name = ""; 
SetName(ref name); 

詳細については誰が説明できますか?ありがとう

答えて

1

C#stringのデータ型には、次のプロパティがあります。 •文字列は参照型ですが、値型のように動作します。 •文字列は変更できません。つまり、文字列を変更するたびに新しい文字列が作成され、参照変数が新しく作成された文字列への参照を変更します。

オブジェクト型への参照変数は、常に参照によって渡されます(難しいように見えるかもしれませんが、読んでいればそれを得るでしょう:))。 しかし、文字列の場合、デフォルトで渡される参照変数は、(refキーワードを明示的に使用しない限り)値によって渡されます。したがって、次の場合に :新しい参照変数はハロー列と同じ場所を指すMyFucntionに作成され

String hello = "Hello"; 
MyFunction(hello); 

。しかし、MyFucntionの内部でhello関数を変更すると、実際に新しく作成された参照変数の内容が変更されます。メインインサイド

//let's create a string and pass it to a function as value and reference type 
String str = "Hello World"; 
StringRefernecePassedByValue(str, ref str); 
//the reference that was passed by value is the one that is the actual reference 
//other one was a new refernece variable that has a copy of the reference 
Console.WriteLine("Actual String: " + str); 

と呼ばれる機能:

//The body of the function 
static void StringRefernecePassedByValue(String valStr,ref String refStr) 
{ 
    //Both of the passed reference variable are pointing to the same location 
    Console.WriteLine("Are equal?: " + ReferenceEquals(valStr, refStr)); 

    //let's change the strings 
    valStr = "Hello1";//a new string is created and now the valStr refer to it 
    refStr = "Hello2";//a new string is created and now the refStr refer to it 

    //let's confirm the output 
    Console.WriteLine("Passed by Value: " + valStr); 
    Console.WriteLine("Passed by Reference: " + refStr); 

    //now both are changed are are no more refering to the same location 
    Console.WriteLine("Are equal?: " + ReferenceEquals(valStr, refStr)); 
} 

は、次のコードを考えてみましょう:

void MyFuntion(String hello) 
{ 
    //a new string will be created and the reference value of the 
    //local hello will be changed 
    hello = "Bye"; 
} 

のは、別の例の助けを借りて、より詳細に取得してみましょう出力は:

メインインサイド

//a user defined datatype 
class Student 
{ 
    public String name { get; set; } 
    public String cgpa { get; set; } 
} 

//let's observe in case of Custom type 
Student student = new Student(); 
student.name = "Ali"; 
student.cgpa = "3.5"; 

ClassRefernecePassedByValue(student, ref student); 
Console.WriteLine("Actual String: " + student.name); 

呼び出される関数:

//the body of function 
static void ClassRefernecePassedByValue(Student valStd, ref Student refStd) 
{ 
    //Both of the passed reference variable are pointing to the same location 
    Console.WriteLine("Are equal?: " + ReferenceEquals(valStd, refStd)); 

    //let's change the objects 
    valStd.name = "Joseph";//changing the object refered by valStd 
    refStd.name = "Mick";//changing the object refered by refStd 

    Console.WriteLine("Passed by Value: " + valStd.name); 
    Console.WriteLine("Passed by Reference: " + refStd.name); 

    //now both are same 
    Console.WriteLine("Are equal?: " + ReferenceEquals(valStd, refStd)); 
} 

出力3210

Are equal?: True 
Passed by Value: Hello1 
Passed by Reference: Hello2 
Are equal?: False 
Actual String: Hello2 

今度は、ユーザー定義型のために上記のことをやってみましょう:

Are equal?: True 
Passed by Value: Mick 
Passed by Reference: Mick 
Are equal?: True 
Actual String: Mick 

したがって、関数に渡されたときの文字列への参照は、実際には別の文字列参照変数へのコピーされた参照を含む新しい参照変数を作成しますが、stringは不変型なので、変数が変化すると、実際の参照変数は変更されません。 enter image description here

もさらに理解するために、あなたは完全なコードを取得することができますhere

3

これは、変数の値を変更し、参照型オブジェクトの状態を変更することの違いです。

Employeeでは、後者を行います。 では、あなたは前者をやっています。

参照型では、オブジェクトへの参照がコピーされて渡されます。このため、eを渡すだけで従業員の名前を変更することができます。しかし、方法の中でeを再割り当てすればどうなりますか?

// in the method 
e = null; 

は、渡されたenullになるのだろうか?いいえ。これは、の参照ポイントを別のものにコピーしているためです。従業員を作成したときの元の参照とは関係ありません。

文字列も参照型であるため、これはstringと同じことです。渡された文字列をメソッド内の別のものに変更した場合:

myString = "hello"; 

変更はメソッドの外部に反映されません。理論的には、メソッド内で文字列の状態を変更することができ、メソッドの外側に反映されます。ただし、文字列は不変です(状態を変更できるようなものは公開しません)。

これにrefを追加すると、あなたのオブジェクトを参照する参照の参照が渡されるため、これが可能になります。したがって、メソッドの内部で要素を再割り当てすることができ、変更は外部に反映されます。

0

メソッド呼び出し中にrefキーワードで文字列を渡さないと、文字列の新しいインスタンスが作成され、文字列の新しいインスタンスに変更が加えられます。メソッドを返すと、渡された文字列値は影響を受けません。

関連する問題