ماذا المرجع ، فال والخروج يعني على طريقة المعلمات ؟
سؤال
أنا أبحث عن واضحة وموجزة ودقيقة الإجابة.
بطبيعة الحال الإجابة الفعلية ، على الرغم من وصلات إلى تفسيرات جيدة موضع ترحيب.
هذا ينطبق أيضا على VB.Net لكن الكلمات مختلفة - ByRef
و ByVal
.
المحلول
بشكل افتراضي (في C#), تمرير كائن إلى وظيفة في الواقع يمر نسخة من الإشارة إلى هذا الكائن.تغيير المعلمة نفسها فقط بتغيير قيمة المعلمة ، وليس المتغير الذي تم تحديده.
void Test1(string param)
{
param = "new value";
}
string s1 = "initial value";
Test1(s1);
// s1 == "initial value"
باستخدام out
أو ref
يمر إشارة إلى المتغير المحدد في استدعاء الدالة.أي تغييرات تطرأ على قيمة out
أو ref
المعلمة سيتم تمريرها إلى المتصل.
سواء out
و ref
تتصرف بشكل مماثل باستثناء فارق واحد بسيط: ref
معلمات مطلوبة initialised قبل الدعوة ، في حين out
المعلمات يمكن uninitialised.قبل التمديد ، ref
المعلمات مضمونة initialised في بداية طريقة ، في حين out
المعلمات معاملة uninitialised.
void Test2(ref string param)
{
param = "new value";
}
void Test3(out string param)
{
// Use of param here will not compile
param = "another value";
}
string s2 = "initial value";
string s3;
Test2(ref s2);
// s2 == "new value"
// Test2(ref s3); // Passing ref s3 will not compile
Test3(out s2);
// s2 == "another value"
Test3(out s3);
// s3 == "another value"
تحرير:كما dp يشير الفرق بين out
و ref
هو فقط ينفذ من قبل برنامج التحويل البرمجي C#, ليس CLR.بقدر ما أعرف, VB لا يوجد لديه أي ما يعادل out
وتنفذ ref
(كما ByRef
) فقط ، مطابقة دعم CLR.
نصائح أخرى
واحدة ملاحظة إضافية عن الحكم مقابلمن:الفرق بين الاثنين هو القسري من قبل برنامج التحويل البرمجي C#.CLR لا يميز بين بين و المرجع.وهذا يعني أنه لا يمكن أن يكون لديك طريقتين التواقيع تختلف فقط من قبل أو المرجع
void foo(int value) {}
// Only one of the following would be allowed
// valid to overload with ref
void foo(ref int value) {}
// OR with out
void foo(out int value) {}
out
يعني أن المعلمة سوف يكون initialised من طريقة:
int result; //not initialised
if( int.TryParse( "123", out result ) )
//result is now 123
else
//if TryParse failed result has still be
// initialised to its default value (0)
ref
وسوف القوة الكامنة الإشارة إلى أن مرت:
void ChangeMyClass1( MyClass input ) {
input.MyProperty = "changed by 1";
input = null;
//can't see input anymore ...
// I've only nulled my local scope's reference
}
void ChangeMyClass2( ref MyClass input ) {
input.MyProperty = "changed by 2";
input = null;
//the passed reference is now null too.
}
MyClass tester = new MyClass { MyProperty = "initial value" };
ChangeMyClass1( tester );
// now tester.MyProperty is "changed by 1"
ChangeMyClass2( ref tester );
// now tester is null
واحدة من بلدي الأسئلة في ستاكوفيرفلوو يعالج هذا الموضوع أيضا.
فإنه يعالج عن "تمر بها المرجعية" و "تمر قيمة" في أنواع مختلفة من اللغات ، c# يتم تضمين لذا ربما يمكنك أن تجد بعض المعلومات الإضافية هناك أيضا.
في الأساس أنه يأتي إلى أسفل إلى:
- ref:المعلمة مع المرجع الكلمة سوف تكون مرت بالرجوع
- من:المعلمة مع أصل الكلمة سوف تكون يعامل معلمة الإخراج
ولكن هذا في الحقيقة أبسط الإجابة, كما هو قليلا أكثر تعقيدا مما هو مذكور هنا