2013-04-06 14 views
5

Neden const kullanımları derleme zamanında değerleriyle değiştiriliyor, ancak yine de derleme içinde yer alıyor? En azından bu, IL DASM ve Reflektör'ün gösterdiği şey..NET const derlenmiş derleme boyutunu etkiliyor

Şu anda çalışma zamanı performansını etkilemeden kod değiştirmeyi daha kolay hale getirmek için birçok sihirli sayı ve dizge tanımlamak üzere const kullanıyorum.

Şimdi bunun kullanılan belleği etkilemediğini biliyorum, ancak hala cep telefonu uygulamaları için çok önemli olan derlenmiş derleme boyutunu etkiliyor. Başka bir dezavantaj, diğer insanların demonte kodlara bakarken büyü numaralarını daha kolay anlamalarıdır.

Derleyicinin (Mono yanı sıra .NET) bunu neden tam olarak yaptığını gerçekten merak ediyorum.

+0

olası bir kopyası [const ile readonly arasındaki fark nedir?] (Http://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly) –

+1

Katılmıyorum Yukarıdaki yinelenen öneri. Bu soru basit bir 'const' vs' readonly' karşılaştırmasından çok daha spesifiktir. – stakx

+1

Stakx'in anlaşmazlığına katılıyorum. ECMA standardını alıntılamak ve açıklamak için – stfx

cevap

6

Bu davranış, ECMA-335 standard (hem .NET hem de Mono'nun uygulamalarıdır) içinde belirtilmiştir. bölüm II.22.9 bir sözü, "sabit": bu yansıma ile görünür olmasına rağmen Constant bilgileri doğrudan, çalışma zamanı davranışını etkilemez

Not (ve dolayısıyla bu şekilde System.Enum.ToString tarafından sağlanan işlevleri gerçekleştirmek için kullanılabilir). Derleyiciler, meta verileri içe aktarırken derleme zamanında bu bilgiyi denetler, ancak eğer kullanılıyorsa, sabitin değeri derleyicinin yaydığı CIL akışına gömülür. Çalışma zamanında Constant tablosuna erişmek için CIL yönergeleri yoktur. olduğu

, const değerleri (onlar olabilir muhtemel nedeni ve performans nedenleriyle) "inlined", ancak bunlar derleyici ve araçları tarafından kontrol edilebilir, böylece yine meta veri tutulur.

hiçbir meta veri alanlarının const -lık için yayılan olsaydı, bu (muhtemelen başkaları — bunlar sadece iki örnek arasında) bu sonuçlara yol açacağı:

  • Derleyiciler veya Reflektör artık ayırt olabilir gibi araçlar düzenli alanlar ve const alanları.
  • System.Reflection kullanarak bir alanı denetlediyseniz, FieldInfo.IsLiteral property artık kullanamazsınız.
+0

+1. –

+0

+1 Yine de, bir insanın Yansıma aracılığıyla “const” alanlarını bulması beklenmediği için kaşları nasıl geliştireceğinden emin değilim. Ayrıca eğlenceli bir şekilde System.Enum.ToString', enum dizisi temsilini almak için en yavaş uygulamadır. Ama sanırım ECMA öyle diyorsa .. – stfx

+0

@stfx: Cevabımın son kısmı ile karıştırıldım. Bu, “const” alanlarının artık meta verilerle keşfedilemeyeceği değil; Onları normal alanlardan ayıramazsınız. Cevabımı düzelttim. – stakx

2

Artan montaj boyutu temel olarak, const -ness hakkında ek meta veriler yayan C# derleyicisinden kaynaklanmaktadır.


Bu kısa programdan hangi çıktıları beklersiniz?

class Program 
{ 
    public const int C = 0; 
    public  int F = 0; 

    static void Main(string[] args) 
    { 
     foreach (FieldInfo field in typeof(Program).GetFields()) 
     { 
      Console.WriteLine("{0}: IsLiteral = {1}", field.Name, field.IsLiteral); 
     } 
    } 
} 

gerçek çıktı şöyledir:

C# kaynağındaki bildirimleri maçları
C: IsLiteral = True 
F: IsLiteral = False 

aynen: İki alanları, bunlardan const biri.

Şimdi C# derleyicisinin Constant meta vermememeye karar verdiğini varsayalım.Sonra çıkış olacaktır: Şimdi her iki alanlar const olarak sivil göründüğü için, C# kaynak koduna göre açıkça yanlıştır

C: IsLiteral = False 
F: IsLiteral = False 

. Nihayet

, en C# derleyicisi hiç C için herhangi bir meta yayacak şekilde karar aldığını varsayalım (yine de "inlines" alanın değerini beri):

F: IsLiteral = False 

Bu yansıma beri de yanlıştır hiçbir daha uzun C# kaynak kodunda açıkça var olan bir alanın varlığını bildirir. En azından benim için, bazı kaş büyütme için iyi bir an olur.

Bu karşı örnekler, const alanları için bile eksiksiz meta verilerin yayınlanmasının neden iyi bir şey olduğunu netleştirmelidir.

+0

Netleştirdiğiniz için teşekkür ederiz. C++ #defines 'e benzer şekilde, gerçekten alan olmadıkları, derlenmedikleri ve yansımalarını yansıtmadığı gibi tercih edildiklerini, ancak tasarımcıların bu yansıma desteğini istediklerini sanıyordum;) – stfx