c# - 'ব্যবহার করা' নির্দেশাবলী নামস্পেস ভিতরে বা বাইরে হতে হবে?




.net namespaces (7)

আমি কিছু C # কোডের উপর StyleCop চালাচ্ছি, এবং এটি রিপোর্টিং রাখে যে আমার নির্দেশাবলী using নামস্পেসের ভিতরে থাকা উচিত।

নামস্থান বাইরে পরিবর্তে using নির্দেশাবলী নির্বাণ জন্য একটি কারিগরি কারণ আছে?


StyleCop ডকুমেন্টেশন অনুযায়ী:

SA1200: ব্যবহার করা ডাইরেক্টাইভসমাস্টব্লেপ্লেড্ডাইননামসেস স্পেস

কারণ অ্যাক্সেস ব্যবহার করে # নামস্পেস উপাদানটির বাইরে স্থাপন করা হয়।

বিধি বর্ণনা এই নিয়মটির লঙ্ঘন ঘটে যখন কোনও ব্যবহারের নির্দেশনা বা ব্যবহারযোগ্য-উদ্বোধন নির্দেশনা একটি নেমস্পেস উপাদানের বাইরে স্থাপন করা হয়, যদি না ফাইলটিতে কোনও নামস্পেস উপাদান থাকে।

উদাহরণস্বরূপ, নিম্নলিখিত কোডটি এই নিয়মটির দুটি লঙ্ঘন ঘটবে।

using System;
using Guid = System.Guid;

namespace Microsoft.Sample
{
    public class Program
    {
    }
}

নিম্নলিখিত কোড, তবে, এই নিয়মটির কোনও লঙ্ঘন ঘটবে না:

namespace Microsoft.Sample
{
    using System;
    using Guid = System.Guid;

    public class Program
    {
    }
}

এই কোডটি কোন কম্পাইলার ত্রুটি ছাড়াই, পরিষ্কারভাবে কম্পাইল হবে। যাইহোক, এটা স্পষ্ট নয় যে গুইড টাইপের সংস্করণ বরাদ্দ করা হচ্ছে। যদি ব্যবহার নির্দেশনা নামস্থান এর ভিতরে সরানো হয়, যেমনটি নীচে দেখানো হয়েছে, একটি কম্পাইলার ত্রুটি ঘটবে:

namespace Microsoft.Sample
{
    using Guid = System.Guid;
    public class Guid
    {
        public Guid(string s)
        {
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Guid g = new Guid("hello");
        }
    }
}

কোডটি নিম্নলিখিত কম্পাইলার ত্রুটির ক্ষেত্রে ব্যর্থ হয়েছে, যা Guid g = new Guid("hello"); পাওয়া গেছে Guid g = new Guid("hello");

CS0576: নামস্থান 'মাইক্রোসফ্ট। নমুনা' একটি উপনাম 'গুইড' সঙ্গে দ্বন্দ্ব একটি সংজ্ঞা রয়েছে

এই কোডটি সিস্টেমের জন্য একটি উপনাম তৈরি করে। গুইড টাইপটি গুইড নামে পরিচিত, এবং এটি একটি নিজস্ব সংযোগকারী ইন্টারফেস সহ গুইড নামে পরিচিত। পরে কোডটি টাইপ গুইডের একটি উদাহরণ তৈরি করে। এই উদাহরণটি তৈরি করতে, কম্পাইলারকে অবশ্যই গিডের দুটি ভিন্ন সংজ্ঞাগুলির মধ্যে নির্বাচন করতে হবে। যখন নাম-উপায়ে নির্দেশনা নামস্থান উপাদানটির বাইরে স্থাপন করা হয়, তখন কম্পাইলার স্থানীয় নামস্থানগুলির মধ্যে সংজ্ঞায়িত গীডের স্থানীয় সংজ্ঞাটি নির্বাচন করবে এবং নামস্থানটির বাইরে সংজ্ঞায়িত ব্যবহার-উদীয়মান নির্দেশিকাটি সম্পূর্ণভাবে উপেক্ষা করবে। এই দুর্ভাগ্যক্রমে, কোড পড়া যখন সুস্পষ্ট নয়।

যখন ব্যবহারকারীর নামের মধ্যে ব্যবহার-উদীয়মান নির্দেশিকাটি স্থাপন করা হয়, তবে কম্পাইলারটিকে একই নামস্পেসের মধ্যে সংজ্ঞায়িত দুটি ভিন্ন, দ্বন্দ্বমূলক গুইড ধরনগুলির মধ্যে নির্বাচন করতে হবে। এই ধরনের উভয় একটি মিলে গঠনকারী প্রদান। কম্পাইলার সিদ্ধান্ত নিতে অক্ষম, তাই এটি কম্পাইলার ত্রুটির পতাকা।

নামস্পেসের বাইরে ব্যবহার-উদীয়মান নির্দেশনাটি স্থাপন করা একটি খারাপ অভ্যাস কারণ এটি এমন পরিস্থিতিতে পরিস্থিতিতে বিভ্রান্তির কারণ হতে পারে, যেখানে এটি কোনও ধরণের সংস্করণটি আসলেই ব্যবহৃত হচ্ছে না তা স্পষ্ট নয়। এই সম্ভাব্য একটি বাগ হতে পারে যা নির্ণয় করা কঠিন হতে পারে।

নামস্পেস এলিমেন্টের মধ্যে উল্লিখিত নির্দেশগুলি স্থাপন করা বাগগুলির উত্স হিসাবে এটি নির্মূল করে।

  1. একাধিক নামস্থান

একক ফাইলের মধ্যে একাধিক নেমস্পেস উপাদান স্থাপন করা সাধারণত একটি খারাপ ধারণা, কিন্তু যদি এটি সম্পন্ন হয়, তবে ফাইলের শীর্ষে বিশ্বব্যাপী পরিবর্তে, প্রতিটি নেমস্পেস উপাদানগুলির মধ্যে সমস্ত নির্দেশাবলী ব্যবহার করা একটি ভাল ধারণা। এটি নামস্থানগুলি শক্তভাবে ঘোরাবে, এবং উপরে বর্ণিত আচরণের ধরন এড়াতে সহায়তা করবে।

এটি উল্লেখ্য যে, যখন নামস্পেসের বাইরে থাকা নির্দেশাবলী ব্যবহার করে কোডটি লিখিত হয়েছে, তখন নামপাসের মধ্যে এই নির্দেশগুলি সরানোর সময় যত্ন নেওয়া উচিত, এটি কোডের সেমেন্টিক্স পরিবর্তন করা হচ্ছে না তা নিশ্চিত করতে। উপরে বর্ণিত হিসাবে, নামস্পেস এলিমেন্টের মধ্যে ওরফে নির্দেশগুলি স্থাপন করা কম্পাইলারটিকে এমন ভাবে বিরোধপূর্ণ ধরনেরগুলির মধ্যে নির্বাচন করতে দেয় যা নির্দেশনাগুলির বাইরে থাকা নির্দেশগুলি বাইরে না থাকলে সেগুলি ঘটবে না।

এই নিয়মটির লঙ্ঘন ঠিক করার জন্য লঙ্ঘনগুলি কীভাবে সমাধান করবেন, নামস্থান উপাদানগুলির মধ্যে সমস্ত নির্দেশাবলী ব্যবহার করে এবং ওরফে নির্দেশগুলি সরান।


আপনার উত্স সমাধানে ব্যবহৃত " রেফারেন্স " ব্যবহার করে ডিফল্ট নামগুলি যদি বাইরে থাকা উচিত এবং এটি "নতুন যোগ রেফারেন্স" হয় তবে এটি একটি ভাল অভ্যাস। এটি একটি ভাল অভ্যাস, এটি আপনাকে নামস্থানটির ভিতরে রাখা উচিত। এই রেফারেন্স যোগ করা হচ্ছে কি পার্থক্য হয়।


আমি বিশ্বাস করি না যে অন্য একটি subtlety অন্যান্য প্রশ্নের দ্বারা আচ্ছাদিত করা হয় যখন আপনি একই নামের সঙ্গে একটি বর্গ এবং নামস্থান আছে।

যখন আপনার নামস্পেসের মধ্যে আমদানি থাকে তখন এটি ক্লাস খুঁজে পাবে। যদি আমদানি নামস্থান বাইরে হয় তবে আমদানি উপেক্ষা করা হবে এবং শ্রেণী এবং নামস্থান সম্পূর্ণ যোগ্যতা অর্জন করতে হবে।

//file1.cs
namespace Foo
{
    class Foo
    {
    }
}

//file2.cs
namespace ConsoleApp3
{
    using Foo;
    class Program
    {
        static void Main(string[] args)
        {
            //This will allow you to use the class
            Foo test = new Foo();
        }
    }
}

//file2.cs
using Foo; //Unused and redundant    
namespace Bar
{
    class Bar
    {
        Bar()
        {
            Foo.Foo test = new Foo.Foo();
            Foo test = new Foo(); //will give you an error that a namespace is being used like a class.
        }
    }
}

আসলে দুটি মধ্যে একটি সূক্ষ্ম (সূক্ষ্ম) পার্থক্য আছে। ফাইল 1.cs এ আপনার নিচের কোডটি কল্পনা করুন:

// File1.cs
using System;
namespace Outer.Inner
{
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

এখন কল্পনা করুন যে কেউ এই প্রকল্পে অন্য ফাইলটি (File2.cs) যোগ করে:

// File2.cs
namespace Outer
{
    class Math
    {
    }
}

কম্পাইলার Outer.Math বাইরে নির্দেশগুলি using করার আগে Outer.Math অনুসন্ধান using , তাই এটি বাইরের খুঁজে পায়। Outer.Math পরিবর্তে System.MathSystem.Math । দুর্ভাগ্যবশত (অথবা সম্ভবত ভাগ্যক্রমে?), Outer.Math এর কোন PI সদস্য নেই, তাই File1 এখন ভাঙা হয়।

আপনি যদি আপনার নেমস্পেস ঘোষণার ভেতরে এই ব্যবহারটি using করেন তবে এটি পরিবর্তন করে:

// File1b.cs
namespace Outer.Inner
{
    using System;
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

এখন কম্পাইলার System অনুসন্ধানের আগে System অনুসন্ধান করে, System.Math খুঁজে পায়, এবং সব ভাল।

কেউ কেউ যুক্তি দিবেন যে Math ব্যবহারকারী-সংজ্ঞায়িত শ্রেণির জন্য একটি খারাপ নাম হতে পারে, কারণ ইতিমধ্যে System মধ্যে একটি রয়েছে; এখানে বিন্দু শুধু একটি পার্থক্য আছে, এবং এটি আপনার কোড রক্ষণাবেক্ষণ প্রভাবিত করে।

এটিও লক্ষ্য করা যায় যে Foo যদি Outer.Inner Outer Outer.Inner থাকে, তবে Outer.Inner । যে ক্ষেত্রে, File2 বিরতি File1 বিরতিতে ouuter.Math যোগ using নির্বিশেষে যেখানে। এটি বোঝায় যে কম্পাইলারটি কোনও using নির্দেশিকা দেখানোর আগে অন্তরঙ্গ এনক্লোজিং নামস্পেস অনুসন্ধান করে।


কারিগরী কারণে উত্তরগুলিতে আলোচনা করা হয় এবং আমি মনে করি শেষ পর্যন্ত ব্যক্তিগত পছন্দগুলি আসে, কারণ পার্থক্যটি বড় নয় এবং উভয়ের জন্য বাণিজ্য বন্ধ রয়েছে। .cs ফাইল তৈরির জন্য ভিজ্যুয়াল স্টুডিওর ডিফল্ট টেমপ্লেট যেমন নামস্থানগুলির বাইরে নির্দেশাবলী ব্যবহার using

stylecop.json ফাইলটি নীচের সাথে প্রকল্প ফাইলের stylecop.json যোগ করে stylecop.json বাইরে নির্দেশগুলি using স্টাইলকপ সামঞ্জস্য করতে পারেন:

{
  "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
    "orderingRules": {
      "usingDirectivesPlacement": "outsideNamespace"
    }
  }
}

আপনি সমাধান স্তরটিতে এই কনফিগার ফাইলটি তৈরি করতে পারেন এবং আপনার সমস্ত প্রকল্পগুলিতে কনফিগারেশন ভাগ করতে 'বিদ্যমান লিঙ্ক ফাইল' হিসাবে আপনার প্রোজেক্টগুলিতে এটি যোগ করতে পারেন।


জেপ্প স্টিগ নিলসেন said , এই থ্রেডটিতে ইতিমধ্যেই উত্তরের উত্তরের উত্তর রয়েছে, কিন্তু আমি মনে করি এই পরিবর্তে সুস্পষ্ট সুস্পষ্টতাও উল্লেখযোগ্য ছিল।

নামস্পেসের অভ্যন্তরে উল্লেখিত নির্দেশগুলি using সংক্ষিপ্ত কোড তৈরি করতে পারে কারণ সেগুলি বাইরে থেকে নির্দিষ্ট করার সময় সম্পূর্ণ যোগ্যতা অর্জন করার প্রয়োজন নেই।

নিচের উদাহরণটি কাজ করে কারণ Foo এবং Bar উভয়ই একই গ্লোবাল নেমস্পেসে, Outer

কোড ফাইল স্থাপন করুন Foo.cs :

namespace Outer.Inner
{
    class Foo { }
}

এবং বার. cs :

namespace Outer
{
    using Outer.Inner;

    class Bar
    {
        public Foo foo;
    }
}

যেটি সংক্ষিপ্ত using জন্য বাইরের নামস্পেসে using যেতে পারে:

namespace Outer
{
    using Inner;

    class Bar
    {
        public Foo foo;
    }
}





code-organization