TLDR: Bu uzun süredir bilinen bir hatadır. İlk olarak 2010'da yazdım:
https://blogs.msdn.microsoft.com/ericlippert/2010/01/18/a-definite-assignment-anomaly/
Zararsızdır ve güvenle göz ardı edebilir ve biraz belirsiz bir hata bulduğunuz için kendinizi tebrik edebilirsiniz.
Derleyici neden Emailkesinlikle atanmalıdır?
Oh, öyle, moda. Göreceğimiz gibi, değişkenin kesinlikle atandığını hangi koşulda ima ettiği konusunda yanlış bir fikri vardır.
Yapı ayrı bir derlemede oluşturulmuşsa bu kod neden derlenir, ancak yapı var olan derlemede tanımlanmışsa derlenmez?
Bu böceğin temel noktası. Hata, C # derleyicisinin yapılar üzerinde nasıl kesin atama denetimi yaptığını ve derleyicinin kütüphanelerden meta verileri nasıl yüklediğinin kesişiminin bir sonucudur.
Bunu düşün:
struct Foo
{
public int x;
public int y;
}
// Yes, public fields are bad, but this is just
// to illustrate the situation.
void M(out Foo f)
{
Tamam, bu noktada ne biliyoruz? ftürü bir değişkenin takma adıdır Foo, bu nedenle depolama alanı zaten ayrılmıştır ve kesinlikle en azından depolama ayırıcısından çıktığı durumdadır. Arayan tarafından değişkene bir değer yerleştirilmişse, bu değer oradadır.
Neye ihtiyacımız var? Biz gerektirir fkesinlikle nerede kontrol yaprakları herhangi bir noktada atanabilir Mnormalde. Yani şöyle bir şey beklersiniz:
void M(out Foo f)
{
f = new Foo();
}
hangi setleri f.xve f.yvarsayılan değerlerine. Peki buna ne dersiniz?
void M(out Foo f)
{
f = new Foo();
f.x = 123;
f.y = 456;
}
Bu da iyi olmalı. Ancak, işte başlatıcı, neden sadece bir an sonra onları uçurmak için varsayılan değerleri atamamız gerekiyor? C # 'ın kesin atama denetleyicisi her alanın atanıp atanmadığını kontrol eder ! Bu yasal:
void M(out Foo f)
{
f.x = 123;
f.y = 456;
}
Ve bu neden yasal olmamalı? Bu bir değer türüdür. fbir değişkendir ve zaten geçerli bir tür değeri içerir Foo, bu yüzden alanları ayarlayalım ve işimiz bitti, değil mi?
Sağ. Peki hata nedir?
Bulduğunuz hata: maliyet tasarrufu olarak, C # derleyicisi başvurulan kitaplıklarda bulunan yapıların özel alanları için meta verileri yüklemez . Bu meta veriler çok büyük olabilir ve her seferinde hepsini belleğe yüklemek için çok az kazanmak için derleyiciyi yavaşlatır.
Ve şimdi bulduğunuz hatanın nedenini çıkarabilmelisiniz. Derleyici, out parametresinin kesinlikle atanıp atanmadığını kontrol ettiğinde, bilinen alanların sayısını kesin olarak başlatılmış alanlarla karşılaştırır ve sizin durumunuzda özel alan meta verileri yüklenmediğinden yalnızca sıfır ortak alanı bilir . Derleyici "gereken sıfır alan, sıfır alan başlatıldı, biz iyiyiz" sonucuna varıyor.
Dediğim gibi, bu hata on yıldan fazla bir süredir var ve sizin gibi insanlar ara sıra yeniden keşfediyor ve bildiriyor. Zararsızdır ve düzeltilmesi pek olası değildir çünkü düzeltmenin neredeyse sıfır faydası vardır, ancak büyük bir performans maliyeti vardır.
Ve elbette hata, projenizdeki kaynak kodunda bulunan yapıların özel alanlarını çoğaltmaz, çünkü derleyici zaten eldeki özel alanlar hakkında bilgi sahibidir.