c# - সরাসরি কাস্টিং বনাম 'হিসাবে' অপারেটর?




casting (12)

নিম্নলিখিত কোড বিবেচনা করুন:

void Handler(object o, EventArgs e)
{
   // I swear o is a string
   string s = (string)o; // 1
   //-OR-
   string s = o as string; // 2
   // -OR-
   string s = o.ToString(); // 3
}

তিন ধরণের ঢালাইয়ের মধ্যে পার্থক্য কী (ঠিক আছে, তৃতীয়টি একটি ঢালাই নয়, তবে আপনি অভিপ্রায় পাবেন)। কোনটি পছন্দ করা উচিত?


  1. কিছু স্পষ্টভাবে অন্য জিনিস হতে হবে যখন ব্যবহার করুন।
  2. কিছু অন্য জিনিস হতে পারে যখন ব্যবহার করুন।
  3. আপনি এটি যত্ন না যখন ব্যবহার করুন কিন্তু আপনি শুধুমাত্র উপলব্ধ স্ট্রিং উপস্থাপনা ব্যবহার করতে চান।

"(স্ট্রিং) o" একটি অবৈধ কাস্টেক্স এক্সপেশনে ফলে কোন সরাসরি কাস্ট নেই।

"o স্ট্রিং হিসাবে" ফলাফলটি নিক্ষেপ করা একটি ব্যতিক্রমের পরিবর্তে একটি অস্পষ্ট রেফারেন্স হতে পারে।

"o.ToString ()" কোনও ধরণের প্রতিলিপি নয়, এটি একটি পদ্ধতি যা বস্তু দ্বারা প্রয়োগ করা হয় এবং এইভাবে এক ভাবে বা অন্যথায় .net এর প্রতিটি বর্গ দ্বারা যে "উদাহরণটি" এর উদাহরণ সহ "কিছু করে"। ক্লাস এটি বলা হয় এবং একটি স্ট্রিং ফেরত।

স্ট্রিং রূপান্তর করতে ভুলবেন না, কনভার্ট। স্ট্রিং (কিছু টাইপ উদাহরণস্বরূপ টাইপ) রয়েছে যেখানে কিছু টাইপ টাইপগুলির একটি সেট, মূলত ফ্রেমওয়ার্কগুলির বেসগুলির মধ্যে একটি।


2 একটি উদ্ভূত টাইপ ঢালাই জন্য দরকারী।

ধরুন একটি প্রাণী হয়:

b = a as Badger;
c = a as Cow;

if (b != null)
   b.EatSnails();
else if (c != null)
   c.EatGrass();

ন্যস্ত ন্যূনতম সঙ্গে একটি খাওয়ানো পেতে হবে।


আমি অপারেটর হিসাবে নিম্নলিখিত সুনির্দিষ্ট মনোযোগ আকর্ষণ করতে চাই:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as

উল্লেখ্য যে অপারেটর শুধুমাত্র রেফারেন্স রূপান্তর, বাতিলযোগ্য রূপান্তর এবং বক্সিং রূপান্তর সঞ্চালন করে। অপারেটর ব্যবহারকারী রূপান্তরিত রূপান্তরগুলির মতো অন্যান্য রূপান্তরগুলি সম্পাদন করতে পারে না, যা কাস্ট এক্সপ্রেশন ব্যবহার করে পরিবর্তিত হওয়া উচিত।


কোনও স্ট্রিং উপস্থাপনা করার চেষ্টা করার সময় (কোনও প্রকারের) যা সম্ভবত অস্পষ্ট হতে পারে, আমি কোডের নিচের লাইনটি পছন্দ করি। এটি কম্প্যাক্ট, এটি ToString (), এবং এটি সঠিকভাবে nulls পরিচালনা করে। O যদি নাল হয়, গুলি স্ট্রিং অন্তর্ভুক্ত হবে। উপসর্গ।

String s = String.Concat(o);

নিম্নলিখিত দুটি রূপ রূপান্তর (কাস্টিং) ফর্ম সি # সমর্থিত হয়:

|

(সিভি

• প্রদত্ত অভিব্যক্তি মধ্যে স্ট্যাটিক টাইপ v থেকে সি রূপান্তর

• কেবলমাত্র যদি গতিশীল প্রকার v হয়, অথবা c এর একটি উপপাদ্য

• যদি না হয়, একটি অবৈধচাস্ট এক্সক্সেশন নিক্ষেপ করা হয়

|

সি হিসাবে ভি

• অ-মারাত্মক বৈকল্পিক (c) v

• সুতরাং, প্রদত্ত অভিব্যক্তি মধ্যে স্ট্যাটিক টাইপ v থেকে সি রূপান্তর

• গতিশীল টাইপ v এর সি নয়, অথবা c এর একটি উপপৃষ্ঠা যদি নাল না করে


মনে হয় তাদের দুটি ধারণাগতভাবে ভিন্ন।

সরাসরি কাস্টিং

ধরন কঠোরভাবে সম্পর্কিত হতে হবে না। এটা স্বাদ সব ধরনের আসে।

  • কাস্টম অন্তর্নিহিত / স্পষ্ট কাস্টিং: সাধারণত একটি নতুন বস্তু তৈরি করা হয়।
  • মান প্রকার প্রযোজ্য: তথ্য হারানো ছাড়া অনুলিপি।
  • মান টাইপ স্পষ্ট: কপি এবং তথ্য হারিয়ে যেতে পারে।
  • আইএস-এ সম্পর্ক: রেফারেন্স টাইপ পরিবর্তন, অন্যথায় ব্যতিক্রম ছোঁড়ে।
  • একই ধরনের: 'কাস্টিং অকার্যকর'।

বস্তুটি অন্য কিছু রূপান্তর করা যাচ্ছে বলে মনে হচ্ছে।

হিসাবে অপারেটর

ধরন একটি সরাসরি সম্পর্ক আছে। যেমন:

  • রেফারেন্স প্রকার: IS-A সম্পর্ক বস্তু সবসময় একই, কেবল রেফারেন্স পরিবর্তন।
  • মূল্য প্রকার: কপি বক্সিং এবং নলাকার ধরনের।

আপনি ভিন্নভাবে বস্তুর হ্যান্ডেল করতে যাচ্ছেন এমন মনে হচ্ছে।

নমুনা এবং আইএল

    class TypeA
    {
        public int value;
    }

    class TypeB
    {
        public int number;

        public static explicit operator TypeB(TypeA v)
        {
            return new TypeB() { number = v.value };
        }
    }

    class TypeC : TypeB { }
    interface IFoo { }
    class TypeD : TypeA, IFoo { }

    void Run()
    {
        TypeA customTypeA = new TypeD() { value = 10 };
        long longValue = long.MaxValue;
        int intValue = int.MaxValue;

        // Casting 
        TypeB typeB = (TypeB)customTypeA; // custom explicit casting -- IL:  call class ConsoleApp1.Program/TypeB ConsoleApp1.Program/TypeB::op_Explicit(class ConsoleApp1.Program/TypeA)
        IFoo foo = (IFoo)customTypeA; // is-a reference -- IL: castclass  ConsoleApp1.Program/IFoo

        int loseValue = (int)longValue; // explicit -- IL: conv.i4
        long dontLose = intValue; // implict -- IL: conv.i8

        // AS 
        int? wraps = intValue as int?; // nullable wrapper -- IL:  call instance void valuetype [System.Runtime]System.Nullable`1<int32>::.ctor(!0)
        object o1 = intValue as object; // box -- IL: box [System.Runtime]System.Int32
        TypeD d1 = customTypeA as TypeD; // reference conversion -- IL: isinst ConsoleApp1.Program/TypeD
        IFoo f1 = customTypeA as IFoo; // reference conversion -- IL: isinst ConsoleApp1.Program/IFoo

        //TypeC d = customTypeA as TypeC; // wouldn't compile
    }

যখন আপনি FindControl পদ্ধতি ব্যবহার করেন তখন কীওয়ার্ডটি asp.net তে ভাল।

Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
     ...
}

এর মানে আপনি টাইপ করা পরিবর্তনশীলকে পরিচালনা করতে পারেন, তারপরে তারপরে আপনি সরাসরি নিক্ষেপের মতো object থেকে এটি নিক্ষেপ করতে পারেন:

object linkObj = this.FindControl("linkid");
if (link != null)
{
     Hyperlink link = (Hyperlink)linkObj;
}

এটি একটি বিশাল জিনিস নয়, তবে এটি কোড এবং পরিবর্তনশীল নিয়োগের লাইন সংরক্ষণ করে, প্লাস এটি আরও বেশি পাঠযোগ্য


যেহেতু কেউ এটি উল্লেখ করেনি, উদাহরণস্বরূপ নিকটতমটি কীওয়ার্ড দ্বারা জাভাতে এটি হল:

obj.GetType().IsInstanceOfType(otherObj)

সমস্ত প্রদত্ত উত্তর ভাল, যদি আমি কিছু যোগ করতে পারি: স্ট্রিংয়ের পদ্ধতি এবং বৈশিষ্ট্যগুলি (যেমন, ToLower) সরাসরি ব্যবহার করার জন্য আপনি লিখতে পারবেন না:

(string)o.ToLower(); // won't compile

আপনি শুধুমাত্র লিখতে পারেন:

((string)o).ToLower();

কিন্তু আপনি পরিবর্তে লিখতে পারে:

(o as string).ToLower();

বিকল্প হিসাবে আরো পাঠযোগ্য (অন্তত আমার মতামত)।


string s = (string)o; // 1

o string না থাকলে InvalidCastException । নাহলে, o নিযুক্ত করে, এমনকি যদি o থাকে।

string s = o as string; // 2

o যদি একটি string না থাকে বা o যদি null হয় তবে এটি null । এই কারণে, আপনি মান প্রকারের সাথে এটি ব্যবহার করতে পারবেন না (অপারেটর সেই ক্ষেত্রে null প্রত্যাবর্তন করতে পারে না)। অন্যথা, s o নির্ধারণ করা হয়।

string s = o.ToString(); // 3

o যদি null হয় তবে একটি NullReferenceException কারণ। o.ToString() যাই হোক না কেন o টাইপ, কোন ব্যাপার কি।

সর্বাধিক রূপান্তরগুলির জন্য 1 ব্যবহার করুন - এটি সহজ এবং সহজবোধ্য। কিছুটা সঠিক টাইপ না থাকলে আমি প্রায় 2 বার ব্যবহার করি না, সাধারণত আমি ব্যতিক্রম হওয়ার আশা করি। ত্রুটিযুক্ত কোডগুলি ব্যবহার করার জন্য ত্রুটিযুক্ত কোডগুলি (যেমন ব্যতিক্রমগুলি ব্যবহার করার পরিবর্তে ফাঁকা null = ত্রুটি) ব্যবহার করে আমি এই রিটার্ন-নুল ধরনের কার্যকারিতাটির কেবলমাত্র প্রয়োজনীয়তা দেখেছি।

3 একটি ঢালাই না এবং শুধু একটি পদ্ধতি আহ্বান। যখন আপনি একটি অ স্ট্রিং বস্তুর স্ট্রিং উপস্থাপনা প্রয়োজন তখন এটি ব্যবহার করুন।


string s = o as string; // 2

পছন্দ করা হয়, এটি ডবল কাস্টিং কর্মক্ষমতা জরিমানা এড়ানো।





casting