কোন বৃহত প্রকল্পে কোনটি ব্যবহার করা ভাল এবং কেন:
#if DEBUG
public void SetPrivateValue(int value)
{ ... }
#endif
অথবা
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
কোন বৃহত প্রকল্পে কোনটি ব্যবহার করা ভাল এবং কেন:
#if DEBUG
public void SetPrivateValue(int value)
{ ... }
#endif
অথবা
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
উত্তর:
এটি আপনি যা যাচ্ছেন তার উপর এটি নির্ভর করে:
#if DEBUG
: এখানের কোডটি এমনকি প্রকাশের সময় আইএল পর্যন্ত পৌঁছাবে না।[Conditional("DEBUG")]
: এই কোডটি আইএল পৌঁছে যাবে, তবে কলার সংকলন করার সময় DEBUG সেট না করা পর্যন্ত পদ্ধতিতে কলগুলি বাদ দেওয়া হবে।ব্যক্তিগতভাবে আমি উভয়ই পরিস্থিতির উপর নির্ভর করে ব্যবহার করি:
শর্তসাপেক্ষে ("ডিইবিইউজি") উদাহরণ: আমি এটি ব্যবহার করি যাতে রিলিজের পরে আমাকে আমার কোডটি ফিরে যেতে হবে না এবং ডিবাগিংয়ের সময় আমি নিশ্চিত হতে চাই যে আমি কোনও টাইপস তৈরি করিনি। এই ফাংশনটি চেক করে যে আমি কোনও আইনের নাম আমার আইএনটিফাইপ্রোটার্টি চেঞ্জড স্টাফগুলিতে ব্যবহার করার চেষ্টা করার সময় সঠিকভাবে টাইপ করেছি।
[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));
}
আপনি যদি না #if DEBUG
একইভাবে সেই ফাংশনে প্রতিটি কল মোড়তে ইচ্ছুক না হন তবে আপনি সত্যিই এটি ব্যবহার করে কোনও ফাংশন তৈরি করতে চান না #if DEBUG
:
#if DEBUG
public void DoSomething() { }
#endif
public void Foo()
{
#if DEBUG
DoSomething(); //This works, but looks FUGLY
#endif
}
বনাম:
[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 উদাহরণ: ডাব্লুসিএফ যোগাযোগের জন্য বিভিন্ন বাইন্ডিং সেটআপ করার চেষ্টা করার সময় আমি এটি ব্যবহার করি।
#if DEBUG
public const String ENDPOINT = "Localhost";
#else
public const String ENDPOINT = "BasicHttpBinding";
#endif
প্রথম উদাহরণে, কোডটি সমস্ত বিদ্যমান, তবে DEBUG চালু না হলে কেবল এড়ানো হবে। দ্বিতীয় উদাহরণে, ডিএনবিইউ সেট করা আছে কি না তার উপর নির্ভর করে কনট ওভারপয়েন্টটি "লোকালহোস্ট" বা "বেসিকএইচটিপিবাইন্ডিং" এ সেট করা আছে।
আপডেট: আমি একটি গুরুত্বপূর্ণ এবং কৌতুকপূর্ণ বিষয়টি স্পষ্ট করতে এই উত্তরটি আপডেট করছি। আপনি যদি ব্যবহারটি বেছে নেন ConditionalAttribute
, মনে রাখবেন যে সংকলনের সময় কলগুলি বাদ দেওয়া হয়েছে, এবং রানটাইম নয় । এটাই:
MyLibrary.dll
[Conditional("DEBUG")]
public void A()
{
Console.WriteLine("A");
B();
}
[Conditional("DEBUG")]
public void B()
{
Console.WriteLine("B");
}
গ্রন্থাগার মুক্তি মোড (অর্থাত কোনো ডিবাগ প্রতীক) বিরুদ্ধে কম্পাইল থাকে, তখন তা চিরকাল কল করতে হবে B()
-এ গিয়ে A()
বাদ দেওয়া, এমনকি যদি একটি কলে A()
কারণ ডিবাগ সমাবেশ আহ্বান সংজ্ঞায়িত করা হয় অন্তর্ভুক্ত করা হয়।
ভাল, এটি লক্ষণীয় যে তারা মোটেও একই জিনিসটি বোঝায় না।
যদি ডিইবিইউজি প্রতীকটি সংজ্ঞায়িত না করা হয়, তবে প্রথম ক্ষেত্রে SetPrivateValue
নিজেকে বলা হবে না ... যদিও দ্বিতীয় ক্ষেত্রে এটি উপস্থিত থাকবে, তবে ডিইবিইউজি প্রতীক ছাড়াই সংকলিত যে কোনও কলকারী সেই কলগুলি বাদ দেবে।
কোড এবং তার সকল কলারের একই হন সমাবেশ এই পার্থক্য নেই কম গুরুত্বপূর্ণ - কিন্তু এটা যে প্রথম ক্ষেত্রে আপনি মানে এছাড়াও থাকতে হবে #if DEBUG
প্রায় কলিং পাশাপাশি কোড।
ব্যক্তিগতভাবে আমি দ্বিতীয় পদ্ধতির সুপারিশ করতাম - তবে আপনাকে তাদের মাথার মধ্যে পার্থক্য পরিষ্কার রাখতে হবে।
আমি নিশ্চিত যে প্রচুর পরিমাণে আমার সাথে একমত হবে না, তবে একজন বিল্ড লোক হিসাবে ক্রমাগত শ্রুতিমধুর হয়ে সময় কাটাচ্ছে "তবে এটি আমার মেশিনে কাজ করে!", আমি এমন অবস্থান গ্রহণ করি যে আপনি কখনও ব্যবহার করবেন না। আপনার যদি টেস্টিং এবং ডিবাগিংয়ের জন্য সত্যই কিছু প্রয়োজন হয় তবে প্রকৃত উত্পাদন কোড থেকে সেই টেস্টাবিলিটিকে আলাদা করতে একটি উপায় বের করুন।
ইউনিট টেস্টগুলিতে বিদ্রূপের সাথে দৃশ্যের বিমূর্তকরণ করুন, আপনি যা পরীক্ষা করতে চান সেগুলির জন্য একটি জিনিসের একটি সংস্করণ তৈরি করুন, তবে বাইনারিগুলির জন্য কোডে ডিবাগের জন্য পরীক্ষা রাখবেন না যা আপনি পরীক্ষার জন্য এবং মুক্তির জন্য লেখেন release এই ডিবাগ পরীক্ষাগুলি কেবলমাত্র ডিভগুলি থেকে সম্ভাব্য বাগগুলি লুকিয়ে রাখে যাতে প্রক্রিয়াটিতে পরে না পাওয়া যায়।
#if debug
আপনার কোডে আপনার কেন বা অনুরূপ কোনও নির্মাণের প্রয়োজন হবে ?
#if DEBUG
যাতে ব্যবহার করি যাতে প্রক্রিয়াটির অংশ হিসাবে ইমেলগুলি প্রেরণ করতে হবে এমন কোনও সিস্টেমের পরীক্ষা করার সময় আমরা অন্যের সাথে দুর্ঘটনাক্রমে স্প্যাম না করি। কখনও কখনও এই কাজের সঠিক সরঞ্জামসমূহ :)
এটি এক হিসাবে দরকারী হতে পারে:
if (Debugger.IsAttached)
{
...
}
Debugger.IsAttached
রিলিজ বিল্ডগুলিতে এমনকি রানটাইমে কল করা উচিত।
প্রথম উদাহরণ দিয়ে, SetPrivateValue
Build এ থাকবে না যদি DEBUG
সংজ্ঞায়িত করা হয় না, দ্বিতীয় উদাহরণ, কল করার SetPrivateValue
বিল্ড মধ্যে উপস্থিত না যদি DEBUG
সংজ্ঞায়িত করা হয় না।
প্রথম উদাহরণ দিয়ে, আপনি কোনো কল মোড়ানো করতে হবে SetPrivateValue
সঙ্গে #if DEBUG
হিসাবে ভাল।
দ্বিতীয় উদাহরণ সহ, কলগুলি SetPrivateValue
বাদ দেওয়া হবে, তবে সচেতন থাকুন যে SetPrivateValue
নিজে থেকে এখনও সংকলিত হবে। আপনি যদি কোনও লাইব্রেরি তৈরি করছেন তবে এটি কার্যকর, সুতরাং আপনার লাইব্রেরির উল্লেখকারী অ্যাপ্লিকেশনটি এখনও আপনার ফাংশনটি ব্যবহার করতে পারে (যদি শর্তটি পূরণ হয়)।
আপনি যদি কলগুলি বাদ দিতে এবং কলির স্থান সংরক্ষণ করতে চান তবে আপনি দুটি কৌশলগুলির সংমিশ্রণটি ব্যবহার করতে পারেন:
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value){
#if DEBUG
// method body here
#endif
}
#if DEBUG
চারপাশে মোড়ানো Conditional("DEBUG")
এই ফাংশনটির কলগুলি সরিয়ে দেয় না, এটি কেবলমাত্র আইএল থেকে ফাংশনটি পুরোপুরি সরিয়ে দেয়, সুতরাং আপনার এখনও উপস্থিত নেই এমন ফাংশনে কল রয়েছে (সংকলন ত্রুটি)।
আসুন ধরে নেওয়া যাক আপনার কোডেও একটি #else
বিবৃতি ছিল যা জোন স্কিটের একটি বিষয়কে সম্বোধন করে একটি নাল স্টাব ফাংশনকে সংজ্ঞায়িত করেছে। দুজনের মধ্যে দ্বিতীয় গুরুত্বপূর্ণ পার্থক্য রয়েছে।
মনে করুন ডিএলএলে #if DEBUG
বা Conditional
ফাংশনটি বিদ্যমান রয়েছে যা আপনার মূল প্রকল্পের নির্বাহযোগ্য দ্বারা রেফারেন্স করা হয়েছে। ব্যবহার করে #if
, শর্তসাপেক্ষের মূল্যায়ন লাইব্রেরির সংকলন সেটিংসের সাথে সম্পাদিত হবে। Conditional
অ্যাট্রিবিউটটি ব্যবহার করে , শর্তাধীনের মূল্যায়ন চালকের সংকলন সেটিংসের সাথে সম্পাদিত হবে।
কাস্টম ব্যবহার করে নেটওয়ার্ক ট্র্যাফিক লগ করতে আমার একটি এসওএপি ওয়েব সার্ভিস এক্সটেনশন রয়েছে [TraceExtension]
। আমি এটি কেবলমাত্র ডিবাগ বিল্ডগুলির জন্য ব্যবহার করি এবং রিলিজ বিল্ডগুলি বাদ দেয় । রিলিজ বিল্ডস থেকে এটি মুছে #if DEBUG
ফেলাতে [TraceExtension]
অ্যাট্রিবিউটটি মোড়ানোর জন্য ব্যবহার করুন ।
#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(...)
সাধারণত প্রোগ্রামআরসিগুলিতে আপনার এটির প্রয়োজন হয় যেখানে আপনি নন-ডিবাগ কোড এবং এটি বেশিরভাগ উইন্ডোজ পরিষেবাদিতেই ডিবাগ চালানোর সিদ্ধান্ত নিতে চান। সুতরাং আমি একটি পঠনযোগ্য ক্ষেত্র ইসডেবগমোড তৈরি করেছি এবং এর মানটি নীচে প্রদর্শিত হিসাবে স্থিতিশীল কন্সট্রাক্টরে সেট করেছি।
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
}