Ne zaman ref vs out ne zaman kullanılır


383

Birisi geçen gün bana outbunun yerine parametre anahtar kelimesini ne zaman kullanmaları gerektiğini sordu ref. Ben (sanırım) refve out(daha önce sorulan ) anahtar kelimeler arasındaki farkı anlamak ve en iyi açıklama ref== inve outher zaman kullanmalı outve değil bazı (varsayımsal veya kod) örnekleri gibi görünüyor ref.

Yana refdaha geneldir, neden şimdiye kadar kullanmak istiyorsunuz out? Sadece sözdizimsel şeker mi?


18
Kullanarak iletilen bir değişken outatanmadan önce okunamaz. refbu kısıtlamaya sahip değildir. İşte bu.
Corey Ogburn

17
Kısacası, sadece bir dış parametre refiken out, içeri / dışarı içindir.
Tim

3
Tam olarak ne elde edemiyorsun?
tnw

4
Ayrıca fonksiyonda outdeğişkenler atanmalıdır.
Corey Ogburn

Teşekkürler Corey. Ama ben zaten öyle değilim. Demek istediğim, bunun yararı nedir. Aslında ref parametresini kullanarak parametre ve yardımcı ayet kullanarak elde edilemeyen bir işlevsellik elde etmek için kullanabileceğimiz bir senaryo gösteren bir örneğe ihtiyacım var.
Rajbir Singh

Yanıtlar:


399

İhtiyacınız outyoksa kullanmalısınız ref.

Verilerin, örneğin maliyetli olabilen başka bir sürece aktarılması gerektiğinde büyük bir fark yaratır. Bu nedenle, yöntem bu değeri kullanmadığında başlangıç ​​değerini sıralamaktan kaçınmak istersiniz.

Bunun ötesinde, bildirimin veya çağrının okuyucusuna başlangıç ​​değerinin alakalı (ve potansiyel olarak korunmuş) veya atıldığını gösterir.

Küçük bir fark olarak, bir çıkış parametresinin başlatılması gerekmez.

Örnek out:

string a, b;
person.GetBothNames(out a, out b);

burada GetBothNames iki değeri atomik olarak almak için bir yöntemdir, yöntem a ve b ne olursa olsun davranışı değiştirmez. Çağrı Hawaii'deki bir sunucuya giderse, ilk değerleri buradan Hawaii'ye kopyalamak bant genişliği israfı demektir. Ref kullanan benzer bir snippet:

string a = String.Empty, b = String.Empty;
person.GetBothNames(ref a, ref b);

a ve b'nin başlangıç ​​değerleri alakalı gibi göründüğü için okuyucuları şaşırtabilir (yöntem adı bunların uygun olmadığını göstermesine rağmen).

Örnek ref:

string name = textbox.Text;
bool didModify = validator.SuggestValidName(ref name);

Burada başlangıç ​​değeri yöntemle ilgilidir.


5
"Durum böyle değil." - Ne demek istediğini daha iyi açıklayabilir misin?
peterchen

3
refVarsayılan değerler için kullanmak istemezsiniz .
C.Evenhuis

155
Gelecek nesiller için: Burada belirtildiği gibi başka hiç kimsenin bahsetmediği bir fark var ; bir outparametre için, yöntem dönmeden önce bir değer atamak için çağıran yöntem gerekir . - Eğer yok olması bir ref parametresi ile bir şey yapmak.
brichins

3
@brichins Lütfen sizin belirttiğiniz bağlantıdaki 'yorumlar (Topluluk Eklemeleri)' bölümüne bakın . VS 2008 belgelerinde düzeltilen bir hatadır.
Bharat Ram V

13
@brichins çağrılan yöntem değil, bir değer atamak için çağrılan yöntem gereklidir. VS 2008 belgelerinde düzeltilen budur.
Mart'ta Segfault

72

Parametrenin kullanılmadığını, yalnızca ayarlandığını göstermek için out kullanın. Bu, arayan kişinin parametreyi her zaman başlattığınızı anlamasına yardımcı olur.

Ayrıca, ref ve out sadece değer türleri için değildir. Ayrıca, bir yöntemin içinden başvuru türünün başvurduğu nesneyi sıfırlamanızı sağlar.


3
+1 Ben de referans türleri için kullanılabileceğini bilmiyordum, güzel açık cevap, teşekkürler
Dale

@brichins: Hayır yapamazsın. outparametreler, işleve girişte atanmamış olarak kabul edilir. İlk olarak kesinlikle bir değer atayana kadar değerlerini denetleyemezsiniz - işlev çağrıldığında parametrenin sahip olduğu değeri kullanmanın hiçbir yolu yoktur.
Ben Voigt

Doğru, dahili atamadan önce değere erişemezsiniz. I parametre kendisi aslında atıfta olabilir yöntemde daha sonra kullanılacak - kilitli değildir. Bunun gerçekten yapılması gerekip gerekmediği farklı bir tartışmadır (tasarım üzerine); Sadece bunun mümkün olduğunu belirtmek istedim. Açıklama için teşekkürler.
brichins

2
@ ดาว: Bir referans türü parametresini ilettiğinizde, ilettiğiniz şey nesnenin kendisi değil referansın değeri olduğu için referans türleriyle kullanılabilir. Yani hala değer geçiyor.
Tarik

38

Bunu anlamsal olarak, refhem "giriş" hem de "çıkış" işlevselliği sağlarken, outyalnızca "çıkış" işlevi sağlar. Dikkate alınması gereken bazı şeyler var:

  1. outparametresini kabul eden yöntemin, dönmeden önce bir noktada, değişkene bir değer atamasını gerektirir. Bu kalıbı, gibi Dictionary<K,V>işlevlere sahip olduğunuz bazı anahtar / değer veri depolama sınıflarında bulabilirsiniz TryGetValue. Bu işlev outalındığında değerin ne olacağını tutan bir parametre alır. Bir değer geçmek arayan için anlamlı olmaz içine öylesine, bu işlev outşu nedenlerden dolayı ( "gerçek" veri olmasa bile, bazı değer çağrısından sonra değişkenin olacağını garanti etmek için kullanılır TryGetValueanahtar mevcut değildir).
  2. outve refbirlikte çalışma koduyla uğraşırken parametreler farklı şekilde sıralanır

Ayrıca, bir yana, referans türleri ve değer türleri değerlerinin doğasında farklılık gösterse de, uygulamanızdaki her değişken, referans türleri için bile bir değeri tutan bir bellek konumuna işaret eder . Sadece referans türleriyle, o hafıza konumundaki değerin başka bir şey olduğu görülür.bellek konumu. Bir işleve değerleri ilettiğinizde (veya başka bir değişken ataması yaptığınızda), bu değişkenin değeri diğer değişkene kopyalanır. Değer türleri için bu, türün tüm içeriğinin kopyalandığı anlamına gelir. Referans türleri için bu, bellek konumunun kopyalandığı anlamına gelir. Her iki durumda da, değişkenin içerdiği verilerin bir kopyasını oluşturur. Bunun sahip olduğu tek gerçek önem atama semantiği ile ilgilidir; bir değişken atarken veya değere göre geçerken (varsayılan), orijinal (veya yeni) değişkene yeni bir atama yapıldığında, diğer değişkeni etkilemez. Referans türleri söz konusu olduğunda, evet, örnekteher iki tarafta da kullanılabilir, ancak bunun nedeni gerçek değişkenin başka bir bellek konumuna sadece bir işaretçi olmasıdır; değişkenin içeriği - bellek konumu - aslında değişmedi.

İle geçerken refanahtar kelime orijinal değişken hem söylüyor ve fonksiyon parametre aslında aynı bellek konumuna işaret edecektir. Bu yine sadece ödev semantiğini etkiler. Değişkenlerden birine yeni bir değer atanırsa, diğeri aynı bellek konumunu gösterdiğinden, yeni değer diğer tarafa yansıtılır.


1
Çağrılan yöntemin bir out parametresine değer ataması gereksiniminin, temel IL tarafından değil, c # derleyicisi tarafından uygulandığını unutmayın. Bu nedenle, VB.NET'te yazılmış bir kütüphane bu kurala uymayabilir.
jmoreno

Ref gibi görünüyor aslında C ++ (*) 'deki kayıttan çıkarma sembolü eşdeğerdir. C # 'daki Passby referansı, C / C ++' ın çift işaretçiler (bir işaretçiye işaretçi) olarak adlandırdığı şeye eşdeğer olmalıdır, bu nedenle ref, 1. işaretçiyi serbest bırakmalı ve çağrılan yöntemin bağlamdaki gerçek nesnenin bellek konumuna erişmesine izin vermelidir.
2014'te

Aslında bir anahtarın bulunmaması durumunda, doğru bir TryGetValueşekilde kullanacağını refve outaçıkça kullanmamayı öneririm .
NetMage

27

Derleme içeriğine bağlıdır (aşağıdaki örneğe bakınız).

outve refher ikisi de değişkenin referansla geçmesini belirtir, ancak değişkenin geçirilmeden refönce başlatılmasını gerektirir; bu, Marshaling bağlamında önemli bir fark olabilir (Interop: UmanagedToManagedTransition veya tersi)

MSDN uyarıyor :

Referans yoluyla geçme kavramını referans türleri kavramıyla karıştırmayın. İki kavram aynı değildir. Bir yöntem parametresi, değer türü veya başvuru türü olup olmadığına bakılmaksızın ref ile değiştirilebilir. Referans olarak iletildiğinde değer türünde bir boks yoktur.

Resmi MSDN Dokümanlarından:

Out anahtar sözcüğü, bağımsız değişkenlerin başvuru ile iletilmesine neden olur. Bu, ref anahtar sözcüğüne benzer, ancak ref, değişkenin geçirilmeden önce başlatılmasını gerektirir

Ref anahtar sözcüğü, bir bağımsız değişkenin değere göre değil başvuruyla iletilmesine neden olur. Referans yoluyla geçirmenin etkisi, yöntemdeki parametrede yapılan herhangi bir değişikliğin, çağıran yöntemdeki temel argüman değişkenine yansıtılmasıdır. Bir referans parametresinin değeri her zaman temeldeki bağımsız değişken değişkeninin değeri ile aynıdır.

Argüman atandığında out ve ref'nin gerçekten aynı olduğunu doğrulayabiliriz:

CIL Örneği :

Aşağıdaki örneği düşünün

static class outRefTest{
    public static int myfunc(int x){x=0; return x; }
    public static void myfuncOut(out int x){x=0;}
    public static void myfuncRef(ref int x){x=0;}
    public static void myfuncRefEmpty(ref int x){}
    // Define other methods and classes here
}

CIL'de talimatlar beklendiği gibi myfuncOutve myfuncRefaynıdır.

outRefTest.myfunc:
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  starg.s     00 
IL_0004:  ldarg.0     
IL_0005:  stloc.0     
IL_0006:  br.s        IL_0008
IL_0008:  ldloc.0     
IL_0009:  ret         

outRefTest.myfuncOut:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  ldc.i4.0    
IL_0003:  stind.i4    
IL_0004:  ret         

outRefTest.myfuncRef:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  ldc.i4.0    
IL_0003:  stind.i4    
IL_0004:  ret         

outRefTest.myfuncRefEmpty:
IL_0000:  nop         
IL_0001:  ret         

nop : işlem yok, ldloc : yükleme yerel, stloc : yığın yerel, ldarg : yükleme bağımsız değişkeni, bs.s : hedeflenen şube ....

(Bkz: CIL talimatlarının listesi )


23

Aşağıda ben C # Out Vs Ref bu codeproject makaleden çekti bazı notlar

  1. Yalnızca bir işlev veya yöntemden birden fazla çıktı beklediğimizde kullanılmalıdır. Yapılar üzerine bir düşünce de aynı şey için iyi bir seçenek olabilir.
  2. REF ve OUT, verinin arayandan callee'ye veya tersi yönde nasıl aktarıldığını belirleyen anahtar kelimelerdir.
  3. REF'de veri iki yoldan geçer. Arayandan callee ve tersi.
  4. In Out verileri callee'den caller'a sadece tek bir yoldan geçer. Bu durumda, Caller çağrıya veri göndermeye çalışırsa, gözden kaçırılır / reddedilir.

Görsel biriyseniz, lütfen pratikte farkı gösteren bu videonuza bakın https://www.youtube.com/watch?v=lYdcY5zulXA

Aşağıdaki görüntü farklılıkları daha görsel olarak göstermektedir

C # Çıkışı Vs Ref


1
one-way, two-wayterimler burada yanlış kullanılabilir. Aslında ikisi de iki
yönlüdür

17

refParametreyi okumayı ve yazmayı planlıyorsanız kullanmanız gerekir . outSadece yazmayı planlıyorsanız kullanmanız gerekir . Aslında, outbirden fazla dönüş değerine ihtiyacınız olduğunda veya çıktı için normal dönüş mekanizmasını kullanmak istemediğinizde (ancak bu nadir olmalıdır) içindir.

Bu kullanım örneklerine yardımcı olan dil mekaniği vardır. Refparametrelerin bir yönteme geçirilmeden önce başlatılmış olmaları gerekir (okuma-yazma olduklarına vurgu yaparak) ve outparametreler bir değer atanmadan okunamaz ve sonunda yazıldıkları garanti edilir yöntem (yalnızca yazma oldukları gerçeğine vurgu yaparak). Bu ilkelere aykırı bir derleme zamanı hatası ile sonuçlanır.

int x;
Foo(ref x); // error: x is uninitialized

void Bar(out int x) {}  // error: x was not written to

Örneğin, int.TryParsea booldeğerini döndürür ve bir out intparametreyi kabul eder :

int value;
if (int.TryParse(numericString, out value))
{
    /* numericString was parsed into value, now do stuff */
}
else
{
    /* numericString couldn't be parsed */
}

Bu, iki değer çıkarmanız gereken durumun açık bir örneğidir: sayısal sonuç ve dönüşümün başarılı olup olmadığı. CLR'nin yazarları out, intdaha önce ne olabileceğini ummadıkları için burayı seçmeye karar verdiler .

Şunlara refbakabilirsiniz Interlocked.Increment:

int x = 4;
Interlocked.Increment(ref x);

Interlocked.Incrementatomik olarak değerini artırır x. Artırmak için okumanız xgerektiğinden, bu refdaha uygun bir durumdur . Geçmeden xönce ne olduğuna tamamen önem veriyorsunuz Increment.

C # 'un bir sonraki sürümünde, outparametrelerdeki değişkeni bildirmek ve sadece çıktı niteliğine daha fazla vurgu yapmak mümkün olacaktır :

if (int.TryParse(numericString, out int value))
{
    // 'value' exists and was declared in the `if` statement
}
else
{
    // conversion didn't work, 'value' doesn't exist here
}

Yanıtınız için teşekkürler zneak. Ama neden bir parametre okumak ve yazmak için kullanamadığımı açıklayabilir misiniz?
Rajbir Singh

@RajbirSingh, çünkü outparametreler mutlaka başlatılmadı, bu yüzden derleyici, bir outşey yazana kadar bir parametreden okumanıza izin vermez .
zneak

zneak, seninle aynı fikirdeyim. Ancak aşağıdaki örnekte bir out parametresi okuma ve yazma olarak kullanılabilir: string name = "myName"; private void OutMethod (out string nameOut) {if (nameOut == "myName") {nameOut = "Rajbir Singh giriş yöntemi"; }}
Rajbir Singh

1
@RajbirSingh, örneğin derlenmiyor. Daha önce hiçbir şey atanmadığı nameOutiçin ififadenizi okuyamazsınız .
zneak

Teşekkürler @zneak. Kesinlikle haklısın. Derlenmez.
Yardımım

7

outdaha kısıtlayıcı bir sürümüdür ref.

Bir yöntem gövdesinde, outyöntemden ayrılmadan önce tüm parametrelere atamanız gerekir . Ayrıca bir parametreye atanan değerler outgöz ardı edilirken, atanmaları refgerekir.

Böylece outşunları yapmanızı sağlar:

int a, b, c = foo(out a, out b);

burada refa ve b atanması gerekir.


Bir şey varsa out, daha az kısıtlanmış versiyonu. refiken ":: değişken kesinlikle Hedefşart atanan değişken kesinlikle atanır Ön koşul" vardır out. Sadece `Hedefşart etti: değişken kesinlikle "atanır (Ve beklendiği gibi, daha az ön koşulları olan bir fonksiyon uygulama gereklidir)
Ben Voigt

@BenVoigt: Sanırım hangi yöne baktığınıza bağlı :) Ben kodlama esnekliği (?) Açısından kısıtlama demek istediğimi düşünüyorum.
leppie

7

Bu sesler nasıl:

dışarı = sadece initialize / bir parametre (parametre boş olmalıdır) iade doldurmak dışarı düz

ref = referans, (belki değerle) standart parametre, ancak işlevi bunu modifiy edebilirsiniz.


out parametresi bir yönteme iletmeden önce bir değer alabilir.
Bence Végert

6

Sen kullanabilirsiniz outbir parametre modifiye edici olarak veya arayüzleri ve delege de genel tür parametre beyanlarında, iki bağlamlarda (her ayrıntılı bilgilere bir bağlantı) bağlamsal anahtar kelime. Bu konuda parametre değiştirici açıklanmaktadır, ancak genel tip parametre bildirimleri hakkında bilgi için bu diğer konuyu görebilirsiniz.

outAnahtar kelime nedenleri argümanlar referans olarak geçirilecek. Bu, refanahtar kelimenin aynısıdır, ancak refdeğişkenin geçirilmeden önce başlatılmasını gerektirir. Bir outparametre kullanmak için , hem yöntem tanımının hem de çağıran yöntemin outanahtar kelimeyi açıkça kullanması gerekir . Örneğin: C #

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}

outBağımsız değişken olarak iletilen değişkenlerin geçirilmeden önce başlatılması gerekmese de, yöntem geri dönmeden önce bir değer atamak için çağrılan yöntem gereklidir.

refVe outanahtar sözcükleri farklı çalışma zamanı davranışlarına neden olsa da , derleme zamanında yöntem imzasının bir parçası olarak değerlendirilmezler. Bu nedenle, tek fark bir yöntemin refbağımsız değişken alması ve diğerinin bağımsız değişken alması yöntemin aşırı yüklenmesi mümkün değildir out. Örneğin, aşağıdaki kod derlenmez: C #

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

Bununla birlikte, bir yöntem bir refveya outbağımsız değişken alırsa ve diğeri bu şekilde değilse, aşırı yükleme yapılabilir : C #

class OutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) { i = 5; }
}

Özellikler değişken değildir ve bu nedenle outparametre olarak iletilemezler.

Dizileri geçirme hakkında bilgi için, bkz. Dizileri Kullanarak Geçme refve out(C # Programlama Kılavuzu).

refVe outanahtar kelimeleri aşağıdaki yöntem türleri için kullanamazsınız :

Async methods, which you define by using the async modifier.

Iterator methods, which include a yield return or yield break statement.

Misal

Bir outyöntemin bildirilmesi, bir yöntemin birden çok değer döndürmesini istediğinizde yararlıdır. Aşağıdaki örnek, outüç değişkeni tek bir yöntem çağrısıyla döndürmek için kullanılır. Üçüncü bağımsız değişkenin null değerine atandığını unutmayın. Bu, yöntemlerin değerleri isteğe bağlı olarak döndürmesini sağlar. C #

class OutReturnExample
{
    static void Method(out int i, out string s1, out string s2)
    {
        i = 44;
        s1 = "I've been returned";
        s2 = null;
    }
    static void Main()
    {
        int value;
        string str1, str2;
        Method(out value, out str1, out str2);
        // value is now 44
        // str1 is now "I've been returned"
        // str2 is (still) null;
    }
}

6

Nasıl kullanmak inveya outveya refC #?

  • İçindeki tüm anahtar kelimeler C#aynı işlevselliğe ancak bazı sınırlara sahip .
  • in argümanlar çağrılan yöntemle değiştirilemez.
  • ref argümanlar değiştirilebilir.
  • ref arayan tarafından kullanılmadan önce başlatılmalıdır, yöntemde okunabilir ve güncellenebilir.
  • out argümanlar arayan tarafından değiştirilmelidir.
  • out argümanların yöntemde başlatılması gerekir
  • Geçirilen değişkenler olarak inbağımsız değişkenler Çağırılırken geçirilmeden önce başlatılmalıdır. Ancak, çağrılan yöntem bir değer atayamaz veya bağımsız değişkeni değiştiremez.

Sen kullanamaz in, refve outyöntemlerin aşağıdaki türlü anahtar kelime:

  • asyncDeğiştiriciyi kullanarak tanımladığınız zaman uyumsuz yöntemler .
  • Bir yield returnveya yield breakdeyimi içeren yineleyici yöntemleri .

5

OP'nin ref ve out kullanımının, daha önce yanlış kurulmuş olan "yöntemin dışında bildirilen bir değer türüne veya yapıya referans" olduğunu açıklamak için.

Bir başvuru türü olan StringBuilder'da ref kullanımını düşünün:

private void Nullify(StringBuilder sb, string message)
{
    sb.Append(message);
    sb = null;
}

// -- snip --

StringBuilder sb = new StringBuilder();
string message = "Hi Guy";
Nullify(sb, message);
System.Console.WriteLine(sb.ToString());

// Output
// Hi Guy

Buna göre:

private void Nullify(ref StringBuilder sb, string message)
{
    sb.Append(message);
    sb = null;
}

// -- snip --

StringBuilder sb = new StringBuilder();
string message = "Hi Guy";
Nullify(ref sb, message);
System.Console.WriteLine(sb.ToString());

// Output
// NullReferenceException

4

Ref olarak iletilen bir argümanın yönteme geçmeden önce başlatılması gerekirken out parametresinin bir yönteme geçmeden önce başlatılması gerekmez.


4

neden hiç kullanmak istedin?

Başkalarına, değişkenin çağrılan yöntemden döndüğünde başlatılacağını bildirmek için!

Yukarıda belirtildiği gibi: "out parametresi için, yöntem döndürülmeden önce bir değer atamak için çağıran yöntem gerekir ."

misal:

Car car;
SetUpCar(out car);
car.drive();  // You know car is initialized.

4

Temel olarak hem refve hem de outnesne / değeri yöntemler arasında geçirmek için

Out anahtar sözcüğü, bağımsız değişkenlerin başvuru ile iletilmesine neden olur. Bu, ref anahtar sözcüğüne benzer, ancak ref, değişkenin geçmeden önce başlatılmasını gerektirir.

out : Bağımsız değişken başlatılmadı ve yöntemde başlatılması gerekiyor

ref : Bağımsız değişken zaten başlatıldı ve yöntemde okunabilir ve güncellenebilir.

Referans türleri için “ref” nin kullanımı nedir?

Verilen başvuruyu farklı bir örneğe değiştirebilirsiniz.

Biliyor musun?

  1. Ref ve out anahtar sözcükleri farklı çalışma zamanı davranışına neden olsa da, derleme zamanında yöntem imzasının bir parçası olarak değerlendirilmezler. Bu nedenle, tek fark bir yöntemin bir ref bağımsız değişkenini ve diğerinin bir çıkış bağımsız değişkenini alması durumunda yöntemler aşırı yüklenemez.

  2. Ref ve out anahtar kelimelerini aşağıdaki yöntem türleri için kullanamazsınız:

    • Eşzamansız değiştiriciyi kullanarak tanımladığınız eşzamansız yöntemler.
    • Verim getirisi veya verim kırılma ifadesini içeren yineleyici yöntemleri.
  3. Özellikler değişken değildir ve bu nedenle dışarı parametreleri olarak iletilemez.


4

C # 7 ile ilgili ek notlar:
C # 7'de değişkenleri kullanarak tahmin etmeye gerek yoktur. Yani böyle bir kod:

public void PrintCoordinates(Point p)
{
  int x, y; // have to "predeclare"
  p.GetCoordinates(out x, out y);
  WriteLine($"({x}, {y})");
}

Şu şekilde yazılabilir:

public void PrintCoordinates(Point p)
{
  p.GetCoordinates(out int x, out int y);
  WriteLine($"({x}, {y})");
}

Kaynak: C # 7'deki yenilikler.


4

Yine de iyi bir özete ihtiyaç duyduğumu hissediyorum.

Özet,

Fonksiyonun içindeyken , değişken veri erişim kontrolünü bu şekilde belirleriz,

in = R

out = R'den önce W gerekir

ref = R + W


Açıklama,

in

Fonksiyon sadece olabilir OKUYUN o değişkeni.

out

Değişken, ilk, çünkü başlatılmak olmamalıdır
fonksiyon MUTLAKA YAZIN önce kendisine OKU .

ref

İşlev bu değişkene READ / WRITE yazabilir .


Neden böyle adlandırılıyor?

Verilerin nerede değiştirildiğine odaklanmak,

in

Veriler sadece (in) fonksiyonuna girilmeden önce ayarlanmalıdır.

out

Veriler yalnızca (çıkış) işlevinden ayrılmadan önce ayarlanmalıdır.

ref

Veriler (in) fonksiyonuna girmeden önce ayarlanmalıdır.
Veriler işlevden çıkmadan (çıkış) önce ayarlanabilir.


belki (giriş / çıkış / ref) (r / wr / rw) olarak yeniden adlandırılmalıdır. ya da belki değil, içeri / dışarı daha hoş bir metafor.
tamircilik

0

C # ver 7.2'den itibarenin geçerli bir anahtar kelime olduğu unutulmamalıdır :

İn parametre değiştiricisi C # 7.2 ve sonrasında mevcuttur. Önceki sürümler derleyici hatası CS8107 üretiyor ("Özellik 'salt okunur başvurular' C # 7.0'da mevcut değil. Lütfen dil sürümü 7.2 veya üstünü kullanın.") Derleyici dili sürümünü yapılandırmak için bkz. C # dil sürümünü seçme.

...

İn anahtar sözcüğü, bağımsız değişkenlerin başvuru tarafından iletilmesine neden olur. Resmi parametreyi, değişken için olması gereken bağımsız değişken için bir diğer ad yapar. Başka bir deyişle, parametre üzerinde herhangi bir işlem bağımsız değişken üzerinde yapılır. Bu, ref veya out anahtar sözcüklerine benzer, ancak bağımsız değişkenlerde çağrılan yöntemle değiştirilemez. Ref bağımsız değişkenleri değiştirilebilirken, out bağımsız değişkenleri çağrılan yöntemle değiştirilmelidir ve bu değişiklikler çağıran bağlamda gözlemlenebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.