সি # তে বক্সিংয়ের ঘটনা


86

আমি সি # তে বক্সিং পরিস্থিতিগুলির সমস্ত পরিস্থিতিতে সংগ্রহ করার চেষ্টা করছি:

  • মান প্রকারকে টাইপে রূপান্তর করা System.Object:

    struct S { }
    object box = new S();
    
  • মান প্রকারকে টাইপে রূপান্তর করা System.ValueType:

    struct S { }
    System.ValueType box = new S();
    
  • গণনা প্রকারের মানকে প্রকারে রূপান্তর করা System.Enum:

    enum E { A }
    System.Enum box = E.A;
    
  • ইন্টারফেস রেফারেন্সে মান ধরণের রূপান্তর করা:

    interface I { }
    struct S : I { }
    I box = new S();
    
  • সি # স্ট্রিং সংমিশ্রণে মান প্রকারগুলি ব্যবহার করে:

    char c = F();
    string s1 = "char value will box" + c;
    

    দ্রষ্টব্য:char ধরণের ধ্রুবকগুলি সংকলনের সময় সংমিশ্রিত হয়

    নোট: সংস্করণ 6.0 C # এর কম্পাইলার যেহেতু সেরা অনুকূল রূপ সংযুক্তকরণের জড়িত bool, char, IntPtr, UIntPtrধরনের

  • মান ধরণের উদাহরণ পদ্ধতি থেকে প্রতিনিধি তৈরি করা:

    struct S { public void M() {} }
    Action box = new S().M;
    
  • মান প্রকারভেদে অ-ওভাররাইড ভার্চুয়াল পদ্ধতিগুলি কল করা:

    enum E { A }
    E.A.GetHashCode();
    
  • isপ্রকাশের অধীনে সি # 7.0 ধ্রুবক নিদর্শনগুলি ব্যবহার :

    int x = …;
    if (x is 42) { … } // boxes both 'x' and '42'!
    
  • সি # টিপল ধরণের রূপান্তরগুলিতে বক্সিং করা:

    (int, byte) _tuple;
    
    public (object, object) M() {
      return _tuple; // 2x boxing
    }
    
  • objectমান ধরণের ডিফল্ট মান সহ টাইপের ptionচ্ছিক পরামিতি :

    void M([Optional, DefaultParameterValue(42)] object o);
    M(); // boxing at call-site
    
  • এর জন্য নিয়ন্ত্রণহীন জেনেরিক ধরণের মান পরীক্ষা করা হচ্ছে null:

    bool M<T>(T t) => t != null;
    string M<T>(T t) => t?.ToString(); // ?. checks for null
    M(42);
    

    দ্রষ্টব্য: এটি কিছু .NET রানটাইমগুলিতে জেআইটি কর্তৃক অনুকূলিত হতে পারে

  • সংকোচহীন বা মান পরীক্ষা টাইপ structসঙ্গে জেনেরিক টাইপ is/ asঅপারেটরদের:

    bool M<T>(T t) => t is int;
    int? M<T>(T t) => t as int?;
    IEquatable<T> M<T>(T t) => t as IEquatable<T>;
    M(42);
    

    দ্রষ্টব্য: এটি কিছু .NET রানটাইমগুলিতে জেআইটি কর্তৃক অনুকূলিত হতে পারে

বক্সিং সম্পর্কে আরও কিছু পরিস্থিতি রয়েছে, সম্ভবত লুকানো আছে, যা আপনি জানেন?


4
আমি কিছুদিন আগে এটির
জর্জ

আপনি দেখিয়েছেন খুব সুন্দর রূপান্তর উপায়। প্রকৃতপক্ষে আমি ২
য়টিকে

12
এটি সম্প্রদায়ের উইকি প্রশ্ন হওয়া উচিত
স্লি

4
অযোগ্য প্রকারগুলি সম্পর্কে কী? private int? nullableInteger
অ্যালানসন

4
@ অ্যালানসন, নালাগুলি ধরণের মান হ'ল এক প্রকারের মান ধরণের
হ'ল

উত্তর:


42

এটি একটি দুর্দান্ত প্রশ্ন!

বক্সিং ঠিক একটি কারণে ঘটে: যখন আমাদের কোনও মানের ধরণের রেফারেন্সের প্রয়োজন হয় । আপনার তালিকাভুক্ত সমস্ত কিছুই এই নিয়মের মধ্যে পড়ে।

উদাহরণস্বরূপ যেহেতু অবজেক্টটি একটি রেফারেন্স টাইপ, কোনও মান প্রকারকে বস্তুতে ingালাইয়ের জন্য একটি মূল্য ধরণের রেফারেন্স প্রয়োজন, যা বক্সিংয়ের কারণ হয় causes

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

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

কয়েক বছর ধরে আমি বিকাশকারীদের সবসময়ই প্রতি একক কেস মুখস্ত করার পরিবর্তে বক্সিংয়ের একক কারণ (আমি উপরে বর্ণিত) মনে রাখার পরামর্শ দিয়েছি, কারণ তালিকাটি দীর্ঘ এবং স্মরণে রাখা শক্ত। এটি আমাদের সি # কোডের জন্য সংকলক কী আইএল কোড উত্পন্ন করে তা বোঝার জন্যও উত্সাহ দেয় (উদাহরণস্বরূপ + স্ট্রিংয়ে স্ট্রিং.কনক্যাটকে একটি কল আসে)। যখন আপনার সন্দেহ হয় যে সংকলকটি কী উত্পন্ন করে এবং যদি বক্সিং হয় তবে আপনি আইএল ডিসসেম্বেবলার (ILDASM.exe) ব্যবহার করতে পারেন। সাধারণত আপনার বাক্স অপকোডের সন্ধান করা উচিত (আইএল বাক্সের অপকোডটি অন্তর্ভুক্ত না করেও বক্সিং ঘটতে পারে এমন একটি ক্ষেত্রে কেবল নীচের আরও বিশদ রয়েছে)।

তবে আমি একমত যে কিছু বক্সিংয়ের ঘটনা কম স্পষ্ট। আপনি তাদের মধ্যে একটি তালিকাভুক্ত করেছেন: মান ধরণের একটি অ-ওভাররাইড পদ্ধতিতে কল করে। আসলে, এটি অন্য কারণে কম স্পষ্ট: আপনি যখন আইএল কোডটি পরীক্ষা করেন আপনি বাক্সটি অপকোড দেখতে পান না, তবে সীমাবদ্ধতাটি অপকোড হয়, তাই আইএল-তেও বক্সিংটি ঘটে না তা স্পষ্ট নয়! এই উত্তরটি আরও দীর্ঘতর হতে কেন রোধ করতে হবে তার সঠিক বিশদে আমি উঠব না ...

স্ট্রাক্ট থেকে বেস ক্লাসের পদ্ধতিটি কল করার সময় কম স্পষ্ট বক্সিংয়ের জন্য আর একটি বিষয়। উদাহরণ:

struct MyValType
{
    public override string ToString()
    {
        return base.ToString();
    }
}

এখানে টসস্ট্রিং ওভাররাইড করা হয়েছে, সুতরাং মাইভালটাইপটিতে টস্ট্রিং কল করা বক্সিং উত্পন্ন করবে না। যাইহোক, বাস্তবায়ন বেস টুস্ট্রিংকে কল করে এবং এর ফলে বক্সিং হয় (আইএল পরীক্ষা করুন!)।

যাইহোক, এই দুটি অপ-সুস্পষ্ট বক্সিং পরিস্থিতি উপরের একক নিয়ম থেকেও প্রাপ্ত। যখন কোনও পদ্ধতির কোনও মান ধরণের বেস শ্রেণিতে ডাকা হয় তখন এই কীওয়ার্ডটি উল্লেখ করার জন্য অবশ্যই কিছু থাকতে হবে । যেহেতু একটি মান ধরণের বেস ক্লাসটি (সর্বদা) একটি রেফারেন্স টাইপ, তাই এই কীওয়ার্ডটি অবশ্যই একটি রেফারেন্স টাইপকে বোঝায় এবং তাই আমাদের একটি মান প্রকারের জন্য একটি রেফারেন্স প্রয়োজন এবং একক নিয়মের কারণে বক্সিং ঘটে।

এখানে আমার অনলাইন .NET কোর্সের একটি অংশের সরাসরি লিঙ্ক রয়েছে যা বক্সিং সম্পর্কে বিস্তারিত আলোচনা করেছে: http://motti.me/mq

আপনি যদি কেবলমাত্র আরও উন্নত বক্সিংগুলির দৃশ্যে আগ্রহী হন তবে এখানে একটি সরাসরি লিঙ্ক রয়েছে (যদিও উপরের লিঙ্কটি আপনাকে আরও সেখানে বেসিক স্টাফ নিয়ে আলোচনা করার সাথে সাথে সেখানে নিয়ে যাবে): http://motti.me/mu

আশা করি এটা কাজে লাগবে!

মোটি


4
যদি কোনও ToString()নির্দিষ্ট মান প্রকারে কল করা হয় যা এটি ওভাররাইড করে না, তবে কী কলটি সাইটে কল করা যাবে, বা পদ্ধতিটি (বক্সিং ছাড়াই) কোনও স্বয়ংক্রিয়-উত্পন্ন ওভাররাইডে প্রেরণ করা হবে যা শৃঙ্খলা ব্যতীত কিছুই করে না (সহ) বক্সিং) বেস পদ্ধতিতে?
সুপারক্যাট

@ সুপের্যাট যে কোনও পদ্ধতিতে যে baseকোনও মান ধরণের কল করে তা কল করার ফলে বক্সিং হয়। এর মধ্যে রয়েছে ভার্চুয়াল পদ্ধতিগুলি যা স্ট্রাক্ট দ্বারা ওভাররাইড করা হয় না এবং এমন Objectপদ্ধতিগুলি অন্তর্ভুক্ত হয় যা ভার্চুয়াল নয় (যেমন GetType())। এই প্রশ্নটি দেখুন ।
akafak Gür

@ ŞafakGür: আমি জানি শেষ ফলাফল বক্সিং হবে। আমি সঠিক পদ্ধতিটি দিয়ে যা ঘটে তা নিয়ে ভাবছিলাম। যেহেতু সংকলক উত্পাদিত আইএল বুঝতে পারে না টাইপটি কোনও মান ধরণের বা রেফারেন্স (এটি জেনেরিক হতে পারে) এটি কলবার্টটি নির্বিশেষে উত্পন্ন করতে চলেছে। জেআইটার জানত যে প্রকারটি কোনও মানের ধরণের কিনা এবং এটি টসস্ট্রিংকে ওভাররাইড করে কিনা, তাই এটি বক্সিং করার জন্য কল-সাইট কোড তৈরি করতে পারে; অন্যথায়, এটি করতে পারে যে struct যে ওভাররাইড না জন্য স্বয়ংক্রিয় উত্পন্ন ToStringএকটি mehtod public override void ToString() { return base.ToString(); }এবং ...
supercat

... বক্সিং পদ্ধতিটি মধ্যে আছে। যেহেতু পদ্ধতিটি খুব সংক্ষিপ্ত হবে, সুতরাং এটি পরে রেখাযুক্ত হতে পারে। পরের পদ্ধতির সাহায্যে জিনিসগুলি করার ফলে স্ট্রাক্টের ToString()পদ্ধতিটি প্রতিবিম্বের মাধ্যমে অন্যের মতো অ্যাক্সেস করার অনুমতি দেয় এবং স্ট্যাটিক প্রতিনিধি তৈরি করতে ব্যবহৃত হত যা স্ট্রাক্ট টাইপটিকে refপ্যারামিটার হিসাবে গ্রহণ করে [এই জাতীয় জিনিসটি উত্তরাধিকারসূত্রে প্রাপ্ত কাঠামোর পদ্ধতিতে কাজ করে] তবে আমি এই জাতীয় প্রতিনিধি তৈরি করার চেষ্টা করেছি এবং এটি কার্যকর হয়নি। কোনও স্ট্রাক্টের ToString()পদ্ধতির জন্য একটি স্ট্যাটিক প্রতিনিধি তৈরি করা সম্ভব এবং যদি তা হয় তবে পরামিতি প্রকারটি কী হওয়া উচিত?
সুপারক্যাট

লিঙ্কগুলি নষ্ট হয়ে গেছে।
OFirD

5

মান প্রকারভেদে নন-ভার্চুয়াল গেটটাইপ () পদ্ধতিটি কল করা:

struct S { };
S s = new S();
s.GetType();

4
GetTypeবক্সিং প্রয়োজন কেবলমাত্র এটি অ-ভার্চুয়াল নয়, তবে ভ্যালু-টাইপ স্টোরেজ অবস্থানগুলি, হ্যাপ অবজেক্টের মতো নয়, "লুকানো" ক্ষেত্র নেই যা GetType()তাদের ধরণ সনাক্ত করতে ব্যবহার করতে পারে।
সুপারক্যাট

নিবন্ধন করুন 1. রানটাইম দ্বারা ব্যবহৃত সংকলক এবং লুকানো ক্ষেত্রের দ্বারা বক্সিং যুক্ত। কম্পাইলার বক্সিং যুক্ত করতে পারে কারণ এটি রানটাইম সম্পর্কে জানে ... ২. যখন আমরা এনাম ভ্যালুতে নন-ভার্চুয়াল টোস্ট্রিং (স্ট্রিং) কল করি তখন এটির জন্য বক্সিংও প্রয়োজন এবং আমি বিশ্বাস করি না যে সংকলক এটি যুক্ত করে কারণ এটি এনাম.টোস্ট্রিং (স্ট্রিং) বাস্তবায়নের বিশদ সম্পর্কে জানে । সুতরাং, আমি মনে করি, আমি বলতে পারি যে "বেস ভ্যালু টাইপ" -তে অ-ভার্চুয়াল পদ্ধতিটি কল করার সময় সবসময় বক্সিং হয় boxing
ভাইচাস্লাভ ইভানভ

আমি Enumএর নিজস্ব কোনও অ-ভার্চুয়াল পদ্ধতি থাকার বিষয়টি বিবেচনা করি নি , যদিও কোনও ToString()পদ্ধতির জন্য Enumতথ্যের টাইপ করার অ্যাক্সেস থাকা দরকার। আমি ভাবছি যদি Object, ValueTypeঅথবা Enumকোনো অ-ভার্চুয়াল পদ্ধতি কোন ধরনের তথ্য ছাড়া তাদের কাজ সঞ্চালন পারে হয়েছে।
সুপারক্যাট

3

মট্টির উত্তরে উল্লেখ করা হয়েছে, কেবল কোড নমুনার সাহায্যে চিত্রিত:

জড়িত পরামিতি

public void Bla(object obj)
{

}

Bla(valueType)

public void Bla(IBla i) //where IBla is interface
{

}

Bla(valueType)

তবে এটি নিরাপদ:

public void Bla<T>(T obj) where T : IBla
{

}

Bla(valueType)

রিটার্ন টাইপ

public object Bla()
{
    return 1;
}

public IBla Bla() //IBla is an interface that 1 inherits
{
    return 1;
}

নাল বিরুদ্ধে অনিয়ন্ত্রিত টি চেক করা

public void Bla<T>(T obj)
{
    if (obj == null) //boxes.
}

গতিশীল ব্যবহার

dynamic x = 42; (boxes)

আরেকটা

enumValue.HasFlag


0
  • System.Collectionsযেমন ArrayListবা তেমন -জেনারিক সংগ্রহগুলি ব্যবহার করে HashTable

মঞ্জুরিপ্রাপ্ত এগুলি আপনার প্রথম মামলার নির্দিষ্ট উদাহরণ, তবে সেগুলি গোচা গোপন করা যেতে পারে। আমি আজও প্রচুর পরিমাণে কোড পেয়েছি যেগুলি এর পরিবর্তে List<T>এবং এগুলি ব্যবহার করে Dictionary<TKey,TValue>


0

অ্যারেলিস্টে কোনও মান ধরণের মান যুক্ত করা বক্সিংয়ের কারণ:

ArrayList items = ...
numbers.Add(1); // boxing to object
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.