DebuggerDisplay Özniteliğini (C#, Visual Basic, F#, C++/CLI) kullanarak hata ayıklayıcıya ne göstereceğini söyleyin
bir DebuggerDisplayAttribute nesnenin, özelliğin veya alanın hata ayıklayıcı değişken pencerelerinde nasıl görüntüleneceğini denetler. Bu öznitelik türlere (sınıflar, yapılar, sabit listeleri, temsilciler) uygulanabilir. Temel türe uygulanırsa, özniteliği bir alt sınıfa da uygulanır.
özniteliği, DebuggerDisplay
tür örnekleri için değer sütununda görüntülenecek bir dize olan tek bir bağımsız değişkene sahiptir. Bu dize ayraçlar ({
ve }
) içerebilir. Bir küme ayracı çifti içindeki metin alan, özellik veya yöntem olarak değerlendirilir.
Bir sınıfın geçersiz kılınmış ToString()
bir yöntemi varsa, hata ayıklayıcı varsayılan {<typeName>}
yerine geçersiz kılınan yöntemini kullanır. Bu nedenle, yöntemini geçersiz kıldıysanız ToString()
, hata ayıklayıcı varsayılan {<typeName>}
yerine geçersiz kılınan yöntemini kullanır ve kullanmanız DebuggerDisplay
gerekmez. Her ikisini de kullanırsanız, DebuggerDisplay
özniteliği geçersiz kılınan ToString()
yöntemden önceliklidir. DebuggerDisplay
özniteliği de bir alt sınıfta geçersiz kılınan ToString()
yöntemden önceliklidir.
Hata ayıklayıcının bu örtük ToString()
çağrıyı değerlendirip değerlendirmediği, Araçlar / Seçenekler / Hata Ayıklama iletişim kutusundaki bir kullanıcı ayarına bağlıdır.
Önemli
Araçlar / Seçenekler / Hata Ayıklama iletişim kutusunda Değişkenlerin ham yapısını göster onay kutusu seçiliyse, DebuggerDisplay
öznitelik yoksayılır.
Dekont
Yerel kod için bu öznitelik yalnızca C++/CLI kodunda desteklenir.
Aşağıdaki tabloda özniteliğin DebuggerDisplay
bazı olası kullanımları ve örnek çıkışlar gösterilmektedir.
Öznitelik | Değer sütununda görünen çıktı |
---|---|
[DebuggerDisplay("x = {x} y = {y}")] ve y alanları x olan bir tür üzerinde kullanılır. |
x = 5 y = 18 |
[DebuggerDisplay("String value is {getString()}")] Parametre söz dizimi diller arasında farklılık gösterebilir. Bu nedenle, dikkatli kullanın. |
String value is [5, 6, 6] |
DebuggerDisplay
adlandırılmış parametreleri de kabul edebilir.
Parametreler | Amaç |
---|---|
Name , Type |
Bu parametreler, değişken pencerelerinin Ad ve Tür sütunlarını etkiler. (Oluşturucuyla aynı söz dizimi kullanılarak dizelere ayarlanabilirler.) Bu parametrelerin aşırı kullanılması veya yanlış kullanılması kafa karıştırıcı bir çıkışa neden olabilir. |
Target , TargetTypeName |
Öznitelik derleme düzeyinde kullanıldığında hedef türü belirtir. |
autoexp.cs dosyası, derleme düzeyinde DebuggerDisplay özniteliğini kullanır. autoexp.cs dosyası, Visual Studio'da .NET nesneleri için kullanılan varsayılan genişletmeleri belirler. DebuggerDisplay özniteliğini kullanma örnekleri için autoexp.cs dosyasını inceleyebilir veya varsayılan genişletmeleri değiştirmek için autoexp.cs dosyasını değiştirebilir ve derleyebilirsiniz. Autoexp.cs dosyasını değiştirmeden önce yedeklediğinizden emin olun.
autoexp.cs oluşturmak için VS2015 için bir Geliştirici Komut İstemi açın ve aşağıdaki komutları çalıştırın
cd <directory containing autoexp.cs>
csc /t:library autoexp.cs
autoexp.dll dosyasındaki değişiklikler bir sonraki hata ayıklama oturumunda alınacaktır.
DebuggerDisplay'de İfadeleri Kullanma
DebuggerDisplay özniteliğindeki küme ayraçları arasında genel bir ifade kullanabilirsiniz ancak bu uygulama önerilmez.
DebuggerDisplay içindeki genel bir ifade, yalnızca hedef türün this
geçerli örneği için işaretçiye örtük erişime sahiptir. İfadenin diğer adlara, yerel ayarlara veya işaretçilere erişimi yoktur. İfade özelliklere başvuruyorsa, bu özelliklerdeki öznitelikler işlenmez. Örneğin, alan count
8 ise C# kodu [DebuggerDisplay("Object {count - 2}")]
görüntülenirObject 6
.
DebuggerDisplay'de ifadelerin kullanılması aşağıdaki sorunlara yol açabilir:
İfadelerin değerlendirilmesi hata ayıklayıcıdaki en pahalı işlemdir ve ifade her görüntülendiğinde değerlendirilir. Bu, kodda adım adım performans sorunlarına neden olabilir. Örneğin, bir koleksiyondaki veya listedeki değerleri görüntülemek için kullanılan karmaşık bir ifade, öğe sayısı büyük olduğunda çok yavaş olabilir.
İfadeler, ifadenin yazıldığı dilin değerlendiricisi tarafından değil, geçerli yığın çerçevesinin dilinin ifade değerlendiricisi tarafından değerlendirilir. Bu, diller farklı olduğunda öngörülemeyen sonuçlara neden olabilir.
bir ifadenin değerlendirilmesi uygulamanın durumunu değiştirebilir. Örneğin, bir özelliğin değerini ayarlayan bir ifade, yürütülen koddaki özellik değerini sessize alır.
İfade değerlendirmesinin olası sorunlarını azaltmanın bir yolu, işlemi gerçekleştiren ve dize döndüren bir özel özellik oluşturmaktır. DebuggerDisplay özniteliği daha sonra bu özel özelliğin değerini görüntüleyebilir. Aşağıdaki örnek bu düzeni uygular:
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public sealed class MyClass
{
public int count { get; set; }
public bool flag { get; set; }
private string DebuggerDisplay
{
get
{
return string.Format("Object {0}", count - 2);
}
}
}
",nq" soneki, ifade değerlendiricisine son değeri görüntülerken tırnak işaretlerini kaldırmasını söyler (nq = tırnak yok).
Örnek
Aşağıdaki kod örneğinde ve DebuggerTypeProxy
ile DebuggerBrowsable
birlikte öğesinin nasıl kullanılacağı DebuggerDisplay
gösterilmektedir. İzleme penceresi gibi bir hata ayıklayıcısı değişkenleri penceresinde görüntülendiğinde şuna benzer bir genişletme oluşturur:
Adı | Değer | Türü |
---|---|---|
Tuş | "üç" | object {string} |
Değer | 3 | {int} nesnesi |
[DebuggerDisplay("{value}", Name = "{key}")]
internal class KeyValuePairs
{
private IDictionary dictionary;
private object key;
private object value;
public KeyValuePairs(IDictionary dictionary, object key, object value)
{
this.value = value;
this.key = key;
this.dictionary = dictionary;
}
public object Key
{
get { return key; }
set
{
object tempValue = dictionary[key];
dictionary.Remove(key);
key = value;
dictionary.Add(key, tempValue);
}
}
public object Value
{
get { return this.value; }
set
{
this.value = value;
dictionary[key] = this.value;
}
}
}
[DebuggerDisplay("{DebuggerDisplay,nq}")]
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable
{
public Hashtable hashtable;
public MyHashtable()
{
hashtable = new Hashtable();
}
private string DebuggerDisplay { get { return "Count = " + hashtable.Count; } }
private class HashtableDebugView
{
private MyHashtable myhashtable;
public HashtableDebugView(MyHashtable myhashtable)
{
this.myhashtable = myhashtable;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public KeyValuePairs[] Keys
{
get
{
KeyValuePairs[] keys = new KeyValuePairs[myhashtable.hashtable.Count];
int i = 0;
foreach (object key in myhashtable.hashtable.Keys)
{
keys[i] = new KeyValuePairs(myhashtable.hashtable, key, myhashtable.hashtable[key]);
i++;
}
return keys;
}
}
}
}