Hangi büyük bir projede kullanmak daha iyidir ve neden:
#if DEBUG
public void SetPrivateValue(int value)
{ ... }
#endif
veya
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
Hangi büyük bir projede kullanmak daha iyidir ve neden:
#if DEBUG
public void SetPrivateValue(int value)
{ ... }
#endif
veya
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
Yanıtlar:
Gerçekten ne istediğinize bağlı:
#if DEBUG
: Buradaki kod serbest bırakıldığında IL'ye bile ulaşmayacak.[Conditional("DEBUG")]
: Bu kod IL'ye ulaşacaktır, ancak arayan derlendiğinde DEBUG ayarlanmadığı sürece yönteme çağrılar atlanacaktır.Şahsen ben duruma bağlı olarak her ikisini de kullanıyorum:
Koşullu ("DEBUG") Örnek: Geriye dönüp daha sonra yayın sırasında kodumu düzenlemek zorunda kalmamam için bunu kullanıyorum, ancak hata ayıklama sırasında herhangi bir yazım hatası yapmadığımdan emin olmak istiyorum. Bu işlev, INotifyPropertyChanged öğelerimde kullanmaya çalışırken bir özellik adını doğru yazdığımı denetler.
[Conditional("DEBUG")]
[DebuggerStepThrough]
protected void VerifyPropertyName(String propertyName)
{
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
Debug.Fail(String.Format("Invalid property name. Type: {0}, Name: {1}",
GetType(), propertyName));
}
Bu işleve yapılan #if DEBUG
her çağrıyı aynı şekilde sarmak istemiyorsanız, gerçekten kullanarak bir işlev oluşturmak istemezsiniz #if DEBUG
:
#if DEBUG
public void DoSomething() { }
#endif
public void Foo()
{
#if DEBUG
DoSomething(); //This works, but looks FUGLY
#endif
}
karşı:
[Conditional("DEBUG")]
public void DoSomething() { }
public void Foo()
{
DoSomething(); //Code compiles and is cleaner, DoSomething always
//exists, however this is only called during DEBUG.
}
#if DEBUG örneği: WCF iletişimi için farklı bağlantılar kurmaya çalışırken bunu kullanıyorum.
#if DEBUG
public const String ENDPOINT = "Localhost";
#else
public const String ENDPOINT = "BasicHttpBinding";
#endif
İlk örnekte, kodun tamamı vardır, ancak DEBUG açık olmadığı sürece yok sayılır. İkinci örnekte, DEBUG öğesinin ayarlanıp ayarlanmadığına bağlı olarak const ENDPOINT öğesi "Localhost" veya "BasicHttpBinding" olarak ayarlanır.
Güncelleme: Önemli ve zor bir noktayı açıklığa kavuşturmak için bu cevabı güncelliyoruz. Seçeneğini kullanmayı seçerseniz ConditionalAttribute
, aramaların derleme sırasında değil çalışma sürelerinin dikkate alınmadığını unutmayın . Yani:
MyLibrary.dll
[Conditional("DEBUG")]
public void A()
{
Console.WriteLine("A");
B();
}
[Conditional("DEBUG")]
public void B()
{
Console.WriteLine("B");
}
Kütüphane sürüm modunda (yani hiçbir DEBUG sembolü) karşı derlenmiş zaman, sonsuza çağrısına sahip olacak B()
içinden A()
, atlanmış olsa bile yapılan bir çağrı A()
DEBUG montaj arayarak tanımlanmış olması nedeniyle dahildir.
Aynı şeyi hiç anlamadıklarını belirtmek gerekir.
Eğer DEBUG sembolü tanımlanmamışsa, ilk durumda SetPrivateValue
kendisi çağrılmaz ... ikinci durumda mevcut olacaktır, ancak DEBUG sembolü olmadan derlenen arayanlar bu çağrıları atlayacaktır.
Kod ve tüm arayanları aynı montajdaysa, bu fark daha az önemlidir - ancak ilk durumda arama kodunun etrafında da olması gerektiği anlamına gelir .#if DEBUG
Şahsen ikinci yaklaşımı öneriyorum - ama aralarındaki farkı kafanızda açık tutmanız gerekiyor.
Eminim benimle aynı fikirde değil, ama sürekli "Ama benim makinemde çalışıyor!" Diye işitme yapan bir adam olarak zaman geçirdim, ben de hemen hemen hiç kullanmamalısınız bakış açısını alıyorum. Test ve hata ayıklama için gerçekten bir şeye ihtiyacınız varsa, test edilebilirliği gerçek üretim kodundan ayırmanın bir yolunu bulun.
Birim testlerinde alaycı senaryoları soyutlayın, test etmek istediğiniz bir kerelik senaryolar için bir kereye mahsus sürümler yapın, ancak üretim sürümü için test edip yazdığınız ikili kodlar için hata ayıklama testleri koymayın. Bu hata ayıklama testleri, olası hataları geliştiricilerden gizler, böylece işlemin sonrasına kadar bulunamazlar.
#if debug
, kodunuzda neden benzer bir yapıya ihtiyacınız var ?
#if DEBUG
böylece sürecin bir parçası olarak e-posta iletmesi gereken bir sistemi test ederken başkalarını yanlışlıkla spam etmeyiz. Bazen bunlar iş için doğru araçlardır :)
İlk örnek ile, SetPrivateValue
eğer yapı içinde mevcut olmayacaktır DEBUG
tanımlanmış olan ikinci bir örnek ile, aramalar için SetPrivateValue
, eğer yapı içinde mevcut olmayacaktır DEBUG
tanımlanmamıştır.
İlk örnekte, tüm çağrıları da SetPrivateValue
ile sarmanız gerekir #if DEBUG
.
İkinci örnekte, çağrılar SetPrivateValue
atlanacak, ancak SetPrivateValue
yine de derleneceğini unutmayın. Bu, bir kitaplık oluşturuyorsanız yararlıdır, bu nedenle kitaplığınıza başvuran bir uygulama yine de işlevinizi kullanabilir (koşul karşılanırsa).
Çağrıları atlamak ve arayanın alanından tasarruf etmek istiyorsanız, iki tekniğin bir kombinasyonunu kullanabilirsiniz:
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value){
#if DEBUG
// method body here
#endif
}
#if DEBUG
etrafında Conditional("DEBUG")
hala (derleme hataları) yok işlevine çağrıları yaşıyorsanız bu nedenle, sadece alltogether IL fonksiyonunu kaldırır, bu işleve çağrı kaldırmaz.
Kodunuzun ayrıca #else
, Jon Skeet'in noktalarından birine hitap eden bir boş saplama işlevi tanımlayan bir ifade olduğunu varsayalım . İkisi arasında ikinci önemli bir ayrım var.
#if DEBUG
Veya Conditional
işlevinin, ana proje yürütülebiliriniz tarafından başvurulan bir DLL dosyasında var olduğunu varsayalım . Kullanılarak, #if
koşulun değerlendirilmesi kütüphanenin derleme ayarlarına göre yapılacaktır. Bu Conditional
özniteliği kullanarak, koşullu değerlendirmesi davetlinin derleme ayarlarına göre yapılacaktır.
Bir özel kullanarak ağ trafiğini günlüğe kaydetmek için bir SOAP WebService uzantısı var [TraceExtension]
. Ben sadece Debug derlemeleri için kullanın ve Release derlemeler atlayın . Özniteliği #if DEBUG
sarmak için kullanın ve [TraceExtension]
böylece Release derlemelerinden kaldırın.
#if DEBUG
[TraceExtension]
#endif
[System.Web.Service.Protocols.SoapDocumentMethodAttribute( ... )]
[ more attributes ...]
public DatabaseResponse[] GetDatabaseResponse( ...)
{
object[] results = this.Invoke("GetDatabaseResponse",new object[] {
... parmeters}};
}
#if DEBUG
[TraceExtension]
#endif
public System.IAsyncResult BeginGetDatabaseResponse(...)
#if DEBUG
[TraceExtension]
#endif
public DatabaseResponse[] EndGetDatabaseResponse(...)
Genellikle Program.cs dosyasında, hata ayıklama yapmadan hata ayıklama kodunu çalıştırmaya karar vermek istediğiniz programa ihtiyacınız vardır. Bu yüzden salt okunur bir alan IsDebugMode oluşturdum ve değerini aşağıda gösterildiği gibi statik yapıcıda ayarladım.
static class Program
{
#region Private variable
static readonly bool IsDebugMode = false;
#endregion Private variable
#region Constrcutors
static Program()
{
#if DEBUG
IsDebugMode = true;
#endif
}
#endregion
#region Main
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
if (IsDebugMode)
{
MyService myService = new MyService(args);
myService.OnDebug();
}
else
{
ServiceBase[] services = new ServiceBase[] { new MyService (args) };
services.Run(args);
}
}
#endregion Main
}