সি # যদি / তারপরে ডিবাগ বনাম মুক্তির জন্য নির্দেশনা দেয়


432

সমাধান বৈশিষ্ট্যগুলিতে, আমার একমাত্র প্রকল্পের জন্য কনফিগারেশনটি "রিলিজ" করতে সেট করেছে।

মূল রুটিনের শুরুতে, আমার কাছে এই কোডটি রয়েছে এবং এটি "মোড = ডিবাগ" দেখাচ্ছে। আমারও এই দুটি লাইন একেবারে শীর্ষে রয়েছে:

#define DEBUG 
#define RELEASE

আমি কি সঠিক ভেরিয়েবল পরীক্ষা করছি?

#if (DEBUG)
            Console.WriteLine("Mode=Debug"); 
#elif (RELEASE)
            Console.WriteLine("Mode=Release"); 
#endif

আমার লক্ষ্য হ'ল ডিবাগ বনাম রিলিজ মোডের ভিত্তিতে ভেরিয়েবলের জন্য বিভিন্ন ডিফল্ট সেট করা।


13
আপনি দুটি ডিবাগ এবং প্রকাশের সংজ্ঞা দিচ্ছেন।
এরিক ডাহলভাং

উত্তর:


718

DEBUG/ _DEBUGইতিমধ্যে VS এ সংজ্ঞায়িত করা উচিত।

#define DEBUGআপনার কোডের মধ্যে সরান । নির্দিষ্ট সুনির্দিষ্ট বিল্ডের জন্য বিল্ড কনফিগারেশনে প্রিপ্রেসেসরস সেট করুন।

এটি "মোড = ডিবাগ" মুদ্রণ করার কারণটি আপনার #defineএবং তারপরে এড়িয়ে যায় elif

চেক করার সঠিক উপায় হ'ল:

#if DEBUG
    Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

জন্য পরীক্ষা করবেন না RELEASE


77
আমি যুক্ত করতে চেয়েছিলাম যে যদি কেউ কেবল রিলিজের জন্য পরীক্ষা করতে চান তবে একজন এটি করতে পারেন: # if! DEBUG

3
কেন #ifএবং না #ifdef?
বব স্টেইন

23
@ ববস্টাইন-ভিসিবিোন মনে রাখবেন আমরা এখানে সি # এর কথা বলছি, সি নয় #ifdef, সি / সি ++ এর প্রিপ্রসেসরটির সাথে নির্দিষ্ট, সি # ম্যান্ডেটের ব্যবহার #if
jduncanator

27
@Jess, আমি বিশ্বাস করি না ReSharper এই ভিসুয়াল আউট graying করছেন স্টুডিও হয়
Dakotah Hicock

1
@ ডাকোটা হাইকক এটি সঠিক, আমি পুনঃভাগটি ব্যবহার করি না এবং ভিএস এটি ব্যবহার করে না।
মকোশিছি

294

ডিফল্টরূপে, ভিজ্যুয়াল স্টুডিও DEBUG সংজ্ঞায়িত করে যদি প্রকল্পটি ডিবাগ মোডে সংকলিত হয় এবং এটি যদি রিলিজ মোডে থাকে তবে এটি সংজ্ঞা দেয় না। রিলিজটি ডিফল্টরূপে রিলিজ মোডে সংজ্ঞায়িত হয় না। এর মতো কিছু ব্যবহার করুন:

#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();
}

6
দুর্দান্ত উত্তর, প্রশংসা।
ডুয় ট্রান

210

আমি এটির জন্য #defineনির্দেশের সন্ধানের চেয়ে এটিকে পরীক্ষা করা পছন্দ করি :

if (System.Diagnostics.Debugger.IsAttached)
{
   //...
}
else
{
   //...
}

এই সতর্কতার সাথে অবশ্যই আপনি কোনও কিছু সংকলন করতে এবং ডিবাগ মোডে মোতায়েন করতে পারেন তবে তবুও ডিবাগারটি সংযুক্ত থাকতে পারেননি।


1
ধন্যবাদ! "# সংজ্ঞা" কী কী তা আমি এখনও জানি না তাই এটি দুর্দান্ত সমাধান!
টিম

এবং আমার কেস, আমি যা চাই ঠিক তাই করে। আমি আসলে আমার ডিবাগারটি সংযুক্ত আছে কিনা তা জানতে চাই, কারণ আমি জানি আমার একটি ডিবাগার সংযুক্ত থাকলে আমি কার্যকর করতে চাই না some এটা সত্যিই দারুন!
JFTxJ

1
ব্যক্তিগতভাবে যদি #IF DEBUGডিবাগিং কোডের পরিস্থিতিতে ব্যবহার করা পছন্দ হয় যা শেষ না হওয়া উচিত। প্রোডাকশন কোডের জন্য আমি উপরেরটি ব্যবহার করে একমত
কোপস

10
ব্যবহারের পরিবর্তে এটি করার পিছনে অঙ্কনটি #DEBUGহ'ল এটি যদি আপনার কোডটিতে থাকে এবং সর্বদা পরীক্ষা করা হয় যেখানে #DEBUGউত্তরটি সংকলন সময়ে প্রযোজ্য নয় এমন কোডটি সরিয়ে দেয় যাতে আপনার রান-টাইম চেক না থাকে এবং আপনার। উদাহরণ (বা আপনি যেটি সংকলন করেন) ছোট।
ড্যান

1
@ user34660। বর্ণিত প্রশ্নের উত্তর হ'ল "না", যা আসলে কাউকেই সহায়তা করে না।
স্টিভ স্মিথ

51

আমি # আইটেমের বিশাল ফ্যান নই, বিশেষত যদি আপনি আপনার কোড বেসের চারপাশে এটি ছড়িয়ে দেন কারণ এটি আপনাকে সমস্যা দেয় যেখানে ডাবগ বিল্ডগুলি পাস করে তবে রিলিজ বিল্ড ব্যর্থ হয় যদি আপনি যত্নবান না হন।

সুতরাং আমি এখানে যা নিয়ে এসেছি তা এখানে রয়েছে ( সি # তে আইফডিফ দ্বারা অনুপ্রাণিত ):

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;
    }
}

2
আরে এখন, এটি বেশ সৃজনশীল। আমি সম্পত্তিটি সেট করতে আপনার গুণাবলীর ব্যবহার পছন্দ করি।
কেঞ্চিলদা

3
রিশার্পারে বাগগুলি রিফ্যাক্টর করে আঘাত না পাওয়ার সুবিধা রয়েছে যা বর্তমান শর্তসাপেক্ষ সেটআপের উপর ভিত্তি করে আপনার কোডটিকে বিশৃঙ্খলা করতে পারে।
জাফিন

3
আমি এটি পছন্দ করি তবে আমি ভাবছি কেন পরিষেবাটির পরিবর্তে এটির জন্য সিঙ্গলটন বাস্তবায়ন তৈরি করবেন না। এটি সিস্টেম নির্দিষ্ট এবং এটি আপনাকে সর্বত্র এটি ইনজেকশন দেওয়ার বিষয়ে চিন্তা করতে বাধা দেয়। (আপনি কী এমন দৃশ্যের কল্পনা করতে পারেন যেখানে এই কার্যকারিতাটির বাস্তবায়ন অন্যরকম হতে পারে?
BastanteCaro

1
আমার কাছে এখন এক ক্লাসে একটি সিঙ্গেলন এবং পরিষেবা বাস্তবায়ন রয়েছে যা আমি এখন ব্যবহার করছি যাতে আপনি এটি ব্যবহার করার উপায়টি বেছে নিতে পারেন ... অবশ্যই পরিষেবা বাস্তবায়নের পক্ষে "অনড়" হয়ে যাওয়া সহজ হওয়ার সুবিধা রয়েছে যে আপনি উভয় কোড পাথ পরীক্ষা করতে পারবেন ...
টড থমসন

আমি ভাবছি কেন DebuggingServiceস্ট্যাটিক ক্লাস নয় এবং আপনার ইন্টারফেসের দরকার কেন? আইওসি পাত্রে এটি ব্যবহার করে কি কিছু করা যায়?
বেন

23
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

পদ্ধতিতে Debug.Assertশর্তযুক্ত বৈশিষ্ট্য রয়েছে DEBUG। যদি সংজ্ঞায়িত করা হয় না, কল এবং নিয়োগ isDebug = true করছে কাটানো :

প্রতীকটি সংজ্ঞায়িত হলে, কলটি অন্তর্ভুক্ত করা হয়েছে; অন্যথায়, কল (কলটির পরামিতিগুলির মূল্যায়ন সহ) বাদ দেওয়া হয়েছে।

যদি DEBUGসংজ্ঞায়িত করা isDebugহয় তবে সেট করা হয় true(এবং এতে পাস করা হয় Debug.Assert, যা সে ক্ষেত্রে কিছুই করে না)।


এটি একটি দুর্দান্ত সৃজনশীল সমাধানও। :)
জ্যাক

খুশী হলাম। একটি পুনরাবৃত্তির পরিবর্তনশীলটির জন্য যা ডিবাগ এবং মুক্তির মধ্যে পরিবর্তন হওয়া দরকার ... var iterations = 10; Debug.Assert((iterations = Int32.MaxValue) > 0);
ম্যাট ডেভিস

19

আপনি যদি বিল্ড টাইপের জন্য সংজ্ঞায়িত ভেরিয়েবলটি ব্যবহার করার চেষ্টা করছেন তবে আপনার দুটি লাইন অপসারণ করা উচিত ...

#define DEBUG  
#define RELEASE 

... এগুলি #if (DEBUG) সর্বদা সত্য হতে পারে।

এছাড়াও রিলেসের জন্য কোনও পূর্বনির্ধারিত শর্তসাপেক্ষ সংকলন প্রতীক নেই । আপনি যদি প্রকল্পের বৈশিষ্ট্যগুলিতে যেতে চান তবে বিল্ড ট্যাবে ক্লিক করুন এবং তারপরে জেনারেল শিরোনামের অধীনে শর্তসাপেক্ষ সংকলন চিহ্ন পাঠ্য বাক্সে রিলিজ যুক্ত করুন ।

অন্য বিকল্পটি এটি করা ...

#if DEBUG
    Console.WriteLine("Debug");
#else
    Console.WriteLine("Release");
#endif

7

শীর্ষে আপনার সংজ্ঞাগুলি সরান

#if DEBUG
        Console.WriteLine("Mode=Debug"); 
#else
        Console.WriteLine("Mode=Release"); 
#endif

7

টড থমসনের উত্তরের কিছুটা পৃথক শ্রেণির পরিবর্তে স্থির ফাংশন হিসাবে পরিবর্তিত (জারজ?

public static bool isDebugging() {
    bool debugging = false;

    WellAreWe(ref debugging);

    return debugging;
}

[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
    debugging = true;
}

6

প্রজেক্ট বিল্ড প্রোপার্টিগুলিতে DEBUG ধ্রুবকটি সংজ্ঞায়িত করতে ভুলবেন না। এটি সক্ষম করবে #if DEBUG। আমি একটি পূর্বনির্ধারিত রিলিজ ধ্রুবকটি দেখতে পাচ্ছি না, যাতে এটি বোঝা যায় যে কোনও ডিইবিইউজি ব্লকে নেই রিলিজ মোড।

প্রোজেক্ট বিল্ড প্রোপার্টিগুলিতে DEBUG ধ্রুবক সংজ্ঞায়িত করুন


5

নামস্থান

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;
    }

3

এমন একটি টিপ যা আপনাকে অনেক সময় সাশ্রয় করতে পারে - আপনি বেছে নিলেও তা ভুলে যাবেন না debug বিল্ড কনফিগারেশনের অধীনে (vs2012 / 13 মেনুতে এটি বিল্ড => কনফিগারেশন ম্যানেজারের অধীনে) - এটি পর্যাপ্ত নয়।

আপনার পাবলিশের দিকে মনোযোগ দেওয়া দরকার Configuration:

এখানে চিত্র বর্ণনা লিখুন


0

যেহেতু এই সংকলক নির্দেশিকাগুলির উদ্দেশ্য হ'ল সংকলককে কোড, ডিবাগ কোড, বিটা কোড, বা সম্ভবত আপনার শেষ ব্যবহারকারীদের জন্য প্রয়োজনীয় কোড অন্তর্ভুক্ত না করতে বলা উচিত, বিজ্ঞাপন বিভাগ, যেমন আপনি চান # ডেফাইন অ্যাডপেট আপনার প্রয়োজনের ভিত্তিতে এগুলি অন্তর্ভুক্ত করতে বা মুছে ফেলতে সক্ষম হবেন। আপনার উত্স কোডটি পরিবর্তন না করেই যদি উদাহরণস্বরূপ কোনও অ্যানডেপ্ট অ্যাডডিপ্টে মার্জ করে। তারপরে যা করা দরকার তা হ'ল প্রোগ্রামের বিদ্যমান সংস্করণটির সংকলক বিকল্পগুলির বৈশিষ্ট্য পৃষ্ঠায় # অ্যাডডেপ্ট নির্দেশিকা অন্তর্ভুক্ত করা এবং একটি সংকলন এবং ওয়া লা! সংযুক্ত প্রোগ্রামের কোডটি জীবন্ত স্প্রিংস !.

আপনি কোনও নতুন প্রক্রিয়ার জন্য একটি ঘোষণামূলক ব্যবহার করতে চাইতে পারেন যা প্রাইম টাইমের জন্য প্রস্তুত নয় বা কোডটি প্রকাশের সময় না হওয়া পর্যন্ত সক্রিয় হতে পারে না।

যাইহোক, আমি এটি এটিই করি।


0

আমি আরও ভাল উপায় সম্পর্কে চিন্তা করতে পেয়েছিলাম। এটি আমার সম্পর্কে প্রমাণিত হয়েছে যে # আইফ ব্লকগুলি অন্যান্য কনফিগারেশনে কার্যকরভাবে মন্তব্য করা হয়েছে (ধরে নেওয়া হচ্ছে)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");
        }

0

সংজ্ঞাগুলি সরান এবং শর্তসত ডিবাগ মোডে আছে কিনা তা পরীক্ষা করুন। নির্দেশটি রিলিজ মোডে রয়েছে কিনা তা পরীক্ষা করার দরকার নেই।

এটার মতো কিছু:

#if DEBUG
     Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.