C# إذا/ثم توجيهات Debug مقابل الإصدار
-
21-09-2019 - |
سؤال
في خصائص الحل ، لدي مجموعة تكوين على "الإصدار" لمشروع واحد والوحيد.
في بداية الروتين الرئيسي ، لدي هذا الرمز ، ويظهر "الوضع = التصحيح". لدي أيضًا هذين الخطين في الأعلى:
#define DEBUG
#define RELEASE
هل أختبر المتغير الصحيح؟
#if (DEBUG)
Console.WriteLine("Mode=Debug");
#elif (RELEASE)
Console.WriteLine("Mode=Release");
#endif
هدفي هو تعيين الافتراضات المختلفة للمتغيرات بناءً على وضع الإصدار Debug vs.
المحلول
مسح ال #define DEBUG
في الكود الخاص بك. قم بتعيين المعالجات المسبقة في تكوين الإنشاء لهذا الإنشاء المحدد (يجب تحديد Debug/_debug في VS بالفعل).
السبب في قيامه بطباعة "الوضع = التصحيح" بسبب #define
ثم يتخطى elif
.
أيضا ، الطريقة الصحيحة للتحقق هي:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
لا تتحقق من الإصدار
نصائح أخرى
بشكل افتراضي ، يعرّف Visual Studio التصحيح إذا تم تجميع المشروع في وضع التصحيح ولا يحدده إذا كان في وضع الإصدار. لم يتم تعريف الإصدار في وضع الإصدار بشكل افتراضي. استخدم شيئًا كهذا:
#if DEBUG
// debug stuff goes here
#else
// release stuff goes here
#endif
إذا كنت تريد أن تفعل شيئًا فقط في وضع الإصدار:
#if !DEBUG
// release...
#endif
أيضًا ، تجدر الإشارة إلى أنه يمكنك استخدامه [Conditional("DEBUG")]
السمة على الأساليب التي تعود void
لتنفيذهم فقط إذا تم تعريف رمز معين. سيقوم المترجم بإزالة جميع المكالمات إلى هذه الطرق إذا لم يتم تعريف الرمز:
[Conditional("DEBUG")]
void PrintLog() {
Console.WriteLine("Debug info");
}
void Test() {
PrintLog();
}
أفضل التحقق من ذلك مثل هذا VS يبحث عن #Defines:
if (System.Diagnostics.Debugger.IsAttached)
{
//...
}
else
{
//...
}
مع التحذير من أنه بالطبع يمكنك تجميع ونشر شيء ما في وضع التصحيح ولكن لا يزال لم يعلق على تصحيح الأخطاء.
أنا لست معجبًا كبيرًا بأشياء #IF ، خاصةً إذا قمت بنشرها في جميع أنحاء قاعدة الكود لأنها ستمنحك مشاكل في حالة تمرير تصحيح التصحيح ولكن تفشل بنيات الإصدار إذا لم تكن حذراً.
إذن هذا ما توصلت إليه (مستوحى من #ifdef في C#):
public interface IDebuggingService
{
bool RunningInDebugMode();
}
public class DebuggingService : IDebuggingService
{
private bool debugging;
public bool RunningInDebugMode()
{
//#if DEBUG
//return true;
//#else
//return false;
//#endif
WellAreWe();
return debugging;
}
[Conditional("DEBUG")]
private void WellAreWe()
{
debugging = true;
}
}
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
طريقة Debug.Assert
لديه سمة مشروطة DEBUG
. إذا لم يتم تعريفها ، فإن المكالمة والمهمة isDebug = true
نكون اقصاء:
إذا تم تعريف الرمز ، يتم تضمين المكالمة ؛ خلاف ذلك ، تم حذف المكالمة (بما في ذلك تقييم معلمات المكالمة).
لو DEBUG
ويعرف، isDebug
تم تعيينه على true
(وانتقلت إلى Debug.Assert
الذي لا يفعل شيئًا في هذه الحالة).
إذا كنت تحاول استخدام المتغير المحدد لنوع الإنشاء ، فيجب عليك إزالة الخطين ...
#define DEBUG
#define RELEASE
... هذه سوف تسبب #if (تصحيح) ليكون دائما صحيحا.
أيضا لا يوجد رمز تجميع مشروط افتراضي إطلاق. إذا كنت ترغب في تحديد واحد ، انتقل إلى خصائص المشروع ، انقر فوق يبني علامة التبويب ثم أضف الإصدار إلى رموز التجميع الشرطية مربع النص تحت عام عنوان.
الخيار الآخر هو القيام بذلك ...
#if DEBUG
Console.WriteLine("Debug");
#else
Console.WriteLine("Release");
#endif
قم بإزالة تعريفاتك في الأعلى
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
نسخة معدلة قليلاً (تم تعديلها؟) من الإجابة التي أجراها تود طومسون كدالة ثابتة بدلاً من فئة منفصلة (أردت أن أتمكن من تسميتها في عرض webformbing من فئة ViewUtils التي قمت بتضمينها بالفعل).
public static bool isDebugging() {
bool debugging = false;
WellAreWe(ref debugging);
return debugging;
}
[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
debugging = true;
}
مساحة الاسم
using System.Resources;
using System.Diagnostics;
طريقة
private static bool IsDebug()
{
object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(DebuggableAttribute), false);
if ((customAttributes != null) && (customAttributes.Length == 1))
{
DebuggableAttribute attribute = customAttributes[0] as DebuggableAttribute;
return (attribute.IsJITOptimizerDisabled && attribute.IsJITTrackingEnabled);
}
return false;
}
نصيحة قد توفر لك الكثير من الوقت - لا تنسى ذلك حتى لو اخترت debug
ضمن تكوين الإنشاء (في قائمة VS2012/13 ، يكون ذلك ضمن Build => Configuration Manager) - هذا ليس كافيًا.
تحتاج إلى الانتباه إلى النشر Configuration
, ، كما:
نظرًا لأن الغرض من توجيهات البرمجيات هذه هو إخبار المترجم بعدم تضمين الرمز أو رمز التصحيح أو رمز الإصدار التجريبي أو ربما الرمز الذي يحتاجه جميع المستخدمين النهائيين ، باستثناء القول إن قسم الإعلان أن تكون قادرًا على تضمينها أو إزالتها بناءً على احتياجاتك. دون الحاجة إلى تغيير رمز المصدر الخاص بك إذا كان على سبيل المثال يندمج غير Addept في Addept. ثم كل ما يجب القيام به هو تضمين التوجيه #AdDept في صفحة خصائص خيارات البرمجيات لإصدار موجود من البرنامج والقيام بتجميع و wa la! رمز البرنامج المدمج ينبع على قيد الحياة!.
قد ترغب أيضًا في استخدام عملية إعلانية لعملية جديدة غير جاهزة لوقت الذروة أو لا يمكن أن تكون نشطة في الكود حتى يحين الوقت لإصدارها.
على أي حال ، هذه هي الطريقة التي أفعل بها.
حصلت على التفكير في طريقة أفضل. لقد بزغني أن كتل #if تعلق بشكل فعال في تكوينات أخرى (على افتراض DEBUG
أو RELEASE
; ؛ ولكن صحيح مع أي رمز)
public class Mytest
{
public DateTime DateAndTimeOfTransaction;
}
public void ProcessCommand(Mytest Command)
{
CheckMyCommandPreconditions(Command);
// do more stuff with Command...
}
[Conditional("DEBUG")]
private static void CheckMyCommandPreconditions(Mytest Command)
{
if (Command.DateAndTimeOfTransaction > DateTime.Now)
throw new InvalidOperationException("DateTime expected to be in the past");
}
قم بإزالة التعريفات وتحقق مما إذا كان الشرطي على وضع التصحيح. لا تحتاج إلى التحقق مما إذا كان التوجيه على وضع الإصدار.
شيء من هذا القبيل:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif