টাইপ চেকিং: টাইপফ, গেটটাইপ, নাকি?


1511

আমি অনেক লোককে নিম্নলিখিত কোডটি ব্যবহার করতে দেখেছি:

Type t = typeof(obj1);
if (t == typeof(int))
    // Some code here

তবে আমি জানি আপনি এটিও করতে পারেন:

if (obj1.GetType() == typeof(int))
    // Some code here

অথবা এটা:

if (obj1 is int)
    // Some code here

ব্যক্তিগতভাবে, আমি মনে করি যে সর্বশেষটি সবচেয়ে পরিষ্কার, তবে এখানে কি আমি অনুপস্থিত কিছু নেই? কোনটি ব্যবহার করা সবচেয়ে ভাল, বা এটি ব্যক্তিগত পছন্দ?


27
ভুলে যাবেন না as!
আরসিআইএক্স

82
asসত্যই যদিও চেকিং টাইপ করা হয় না ...
জেসনহ

49
asঅবশ্যই টাইপ-চেকিংয়ের একটি ফর্ম, যতটা বিট is! এটি কার্যকরভাবে isপর্দার আড়ালে ব্যবহার করে এবং এমএসডিএন-এর পুরো জায়গাগুলিতে যেখানে এটি পরিস্কারের তুলনায় কোড পরিষ্কার-পরিচ্ছন্নতার উন্নতি করে সেখানে ব্যবহৃত হয় isisপ্রথমে পরীক্ষা করার পরিবর্তে , একটি কল asএকটি টাইপযুক্ত চলকটি ব্যবহারের জন্য প্রস্তুত করে তোলে: এটি যদি নাল হয় তবে যথাযথভাবে প্রতিক্রিয়া দিন; অন্যথায়, এগিয়ে যান। অবশ্যই কিছু আমি দেখেছি এবং বেশ কিছুটা ব্যবহার করেছি।
জ্যাককন

15
আপনার ক্ষেত্রে এর সিনটিক কাজগুলি ধরে ধরে as/ এর পক্ষে is( স্ট্যাকওভারফ্লো . com / a / 27813381 / 477420 এ আচ্ছাদিত ) পক্ষে উল্লেখযোগ্য পারফরম্যান্সের পার্থক্য রয়েছে ।
আলেক্সি লেভেনকভ

@ সমুসারিন এটি "ব্যবহার" প্রতিবিম্ব ব্যবহার করে না। আপনি যে GetTypeপদ্ধতিতে লিঙ্ক করছেন সেটি হ'ল System.Reflection.Assembly- সম্পূর্ণ আলাদা পদ্ধতি এবং এখানে অপ্রাসঙ্গিক।
কার্ক Woll

উত্তর:


1846

সবই আলাদা।

  • typeof একটি প্রকারের নাম নেয় (যা আপনি সংকলনের সময় নির্দিষ্ট করেন)।
  • GetType একটি উদাহরণের রানটাইম টাইপ পায় gets
  • is উত্তরাধিকার গাছে কোনও উদাহরণ থাকলে সত্যটি ফিরে আসে।

উদাহরণ

class Animal { } 
class Dog : Animal { }

void PrintTypes(Animal a) { 
    Console.WriteLine(a.GetType() == typeof(Animal)); // false 
    Console.WriteLine(a is Animal);                   // true 
    Console.WriteLine(a.GetType() == typeof(Dog));    // true
    Console.WriteLine(a is Dog);                      // true 
}

Dog spot = new Dog(); 
PrintTypes(spot);

কি হবে typeof(T)? এটি সংকলন সময়ে সমাধান করা হয়?

হ্যাঁ. টি সর্বদা প্রকাশের ধরণটি কী। মনে রাখবেন, জেনেরিক পদ্ধতিটি মূলত যথাযথ ধরণের পদ্ধতিগুলির পুরো গোছা। উদাহরণ:

string Foo<T>(T parameter) { return typeof(T).Name; }

Animal probably_a_dog = new Dog();
Dog    definitely_a_dog = new Dog();

Foo(probably_a_dog); // this calls Foo<Animal> and returns "Animal"
Foo<Animal>(probably_a_dog); // this is exactly the same as above
Foo<Dog>(probably_a_dog); // !!! This will not compile. The parameter expects a Dog, you cannot pass in an Animal.

Foo(definitely_a_dog); // this calls Foo<Dog> and returns "Dog"
Foo<Dog>(definitely_a_dog); // this is exactly the same as above.
Foo<Animal>(definitely_a_dog); // this calls Foo<Animal> and returns "Animal". 
Foo((Animal)definitely_a_dog); // this does the same as above, returns "Animal"

29
আহা, সুতরাং যদি আমার কাছে গাড়ি থেকে ফোর্ডের একটি ক্লাস এবং ফোর্ডের উদাহরণ পাওয়া যায় তবে সেই উদাহরণে "হ'ল গাড়ি" পরীক্ষা করা সত্য হবে। বোধ হয়!
জেসনহ

2
স্পষ্ট করার জন্য, আমি সে সম্পর্কে সচেতন ছিলাম, তবে আপনি কোডের নমুনা যুক্ত করার আগে আমি মন্তব্য করেছি। আমি আপনার ইতিমধ্যে দুর্দান্ত উত্তরে কিছু স্পষ্ট ইংরেজী স্পষ্টতা যুক্ত করার চেষ্টা করতে চেয়েছিলাম।
জেসনহ

12
@ শিমি যদি টাইপফের সংকলন সময়ে মূল্যায়ন করা হয় এবং রানটাইম সময়ে গেটটাইপ () মূল্যায়ন করা হয়, তবে তা বোঝা যায় যে গেটটাইপ () সামান্য পারফরম্যান্স হিট করে
সিড্রিক মামো

নতুন কুকুর () এর সম্পর্কে কী?
প্রেরাক কে

7
@ প্রেরাককে new Dog().GetType() is Animalমিথ্যা (এবং আপনার অন্যান্য সংস্করণেও) .GetType()ফেরত দেওয়ার পরে যেহেতু কোনও ধরণের অবজেক্ট প্রদান করে Typeএবং Typeএটি একটি নয় Animal
মার্টেন

194

সংকলনের সময় আপনিtypeof টাইপটি পেতে চাইলে ব্যবহার করুন । কার্যকর করার সময় আপনি টাইপটি পেতে চাইলে ব্যবহার করুন । এটি কাস্ট হিসাবে ব্যবহার করার জন্য খুব কমই এরকম কেস রয়েছে এবং বেশিরভাগ ক্ষেত্রে আপনি যেভাবেই চলকটি ingালাই শেষ করেন।GetTypeis

এখানে একটি চতুর্থ বিকল্প রয়েছে যা আপনি বিবেচনা করেননি (বিশেষত যদি আপনি কোনও ধরণের জিনিস খুঁজে পান যা আপনার পছন্দ মতো হয়); যে ব্যবহার করা হয় as

Foo foo = obj as Foo;

if (foo != null)
    // your code here

এটি কেবলমাত্র একটি কাস্ট ব্যবহার করে যেখানে এই পদ্ধতির:

if (obj is Foo)
    Foo foo = (Foo)obj;

দুটি প্রয়োজন ।

আপডেট (জানুয়ারী 2020):

  • সি # 7+ হিসাবে , আপনি এখন ইনলাইন কাস্ট করতে পারেন, সুতরাং 'হ'ল পদ্ধতিটি এখন একটি কাস্টেও করা যেতে পারে।

উদাহরণ:

if(obj is Foo newLocalFoo)
{
    // For example, you can now reference 'newLocalFoo' in this local scope
    Console.WriteLine(newLocalFoo);
}

4
.NET 4 এর পরিবর্তনের isপরেও কি একটি কাস্ট অভিনয় করা যায়?
আহসটিলে

6
এই উত্তরটি কি সঠিক? এটি সত্য যে আপনি সত্যই কোনও উদাহরণ টাইপফোন () এ পাস করতে পারবেন? আমার অভিজ্ঞতা নং হয়েছে তবে আমি অনুমান করি যে এটি সাধারণত সত্য যে কোনও ঘটনা পরীক্ষা করা রানটাইমের সময় ঘটতে পারে, অন্যদিকে ক্লাস চেক করা সংকলনের সময় করণীয় হতে পারে।
জন কুমবস

4
@ জোন (আপনার কিউটার পরে 4 বছর পরে), না, আপনি কোনও উদাহরণ প্রবেশ করতে পারবেন না typeof(), এবং এই উত্তরটি আপনাকে দেয় তা বোঝায় না। আপনি পরিবর্তে টাইপ পাস, অর্থাৎ, typeof(string)কাজ typeof("foo")করে না।
আবেল

আমি বিশ্বাস করি না যে এই জাতীয় isঅভিনেত্রী অভিনেত্রী হিসাবে অভিনয় করেছেন, বরং আইএলে বিশেষ অভিযান।
আবাটিশ শেভ

3
আমরা এখন করতে পারিif (obj is Foo foo) { /* use foo here */ }
ইভান গার্সিয়া টোপেট

71

1।

Type t = typeof(obj1);
if (t == typeof(int))

এটি অবৈধ, কারণ typeofকেবল প্রকারে কাজ করে, ভেরিয়েবলের উপর নয়। আমি ধরে নিলাম obj1 একটি পরিবর্তনশীল। সুতরাং, এইভাবে typeofস্থিতিশীল, এবং রানটাইম পরিবর্তে সংকলন সময়ে এটির কাজ করে।

2।

if (obj1.GetType() == typeof(int))

এই trueযদি obj1ধরনের ঠিকint । যদি obj1থেকে প্রাপ্ত হয় int, তবে যদি শর্ত থাকে false

3।

if (obj1 is int)

এটি trueযদি obj1হয় intতবে এটি হয় বা এটি বলা ক্লাস থেকে উদ্ভূত হয় int, বা যদি এটি ডাকা ইন্টারফেস প্রয়োগ করে int


1 সম্পর্কে চিন্তা করা, আপনি ঠিক বলেছেন। এবং এখনও, আমি এটি বেশ কয়েকটি কোড নমুনাতে এখানে দেখেছি। এটি টাইপ টি = اعتراض 1 হওয়া উচিত et গেটটাইপ ();
জেসনহ

4
হ্যাঁ, আমিও তাই মনে করি। "টাইপফ (1জেক্ট 1)" যখন আমি এটি চেষ্টা করি তখন সংকলন করে না।
স্কট ল্যাংহাম

4
সিস্টেম থেকে উদ্ভূত হওয়া
অসম্ভব.আইটি 32

টাইপফ (টাইপফ (সিস্টেম.int32)) কী হবে তা বলতে পারবেন
সানা

1
@ সানা, আপনি কেন এটি চেষ্টা করবেন না :) আমি কল্পনা করব যদিও আপনি সিস্টেমের একটি উদাহরণ ফিরে পেয়েছেন। টাইপ যা সিস্টেম.প্রকারের প্রতিনিধিত্ব করে! টাইপফের
স্কট ল্যাংহাম

53
Type t = typeof(obj1);
if (t == typeof(int))
    // Some code here

এটি একটি ত্রুটি। সি # তে টাইপফোর অপারেটর কেবল প্রকারের নাম নিতে পারে, বস্তু নয়।

if (obj1.GetType() == typeof(int))
    // Some code here

এটি কাজ করবে, তবে আপনার প্রত্যাশা মতো নয়। মান ধরণের জন্য, যেমন আপনি এখানে দেখিয়েছেন, এটি গ্রহণযোগ্য, তবে রেফারেন্স প্রকারের জন্য, এটি কেবলমাত্র সত্যটি ফিরে আসবে যদি টাইপটি হুবহু একই রকম ছিল , উত্তরাধিকারের শ্রেণিবিন্যাসের অন্য কোনও কিছু নয়। এই ক্ষেত্রে:

class Animal{}
class Dog : Animal{}

static void Foo(){
    object o = new Dog();

    if(o.GetType() == typeof(Animal))
        Console.WriteLine("o is an animal");
    Console.WriteLine("o is something else");
}

এই মুদ্রণ করবে "o is something else"কারণ ধরন, oহয় Dogনা Animal। আপনি ক্লাসের IsAssignableFromপদ্ধতিটি ব্যবহার করেন তবে আপনি এই কাজটি করতে পারেন Type

if(typeof(Animal).IsAssignableFrom(o.GetType())) // note use of tested type
    Console.WriteLine("o is an animal");

যদিও এই কৌশলটি এখনও একটি বড় সমস্যা ছেড়ে দেয়। যদি আপনার ভেরিয়েবলটি নাল হয়, তবে কলটি GetType()একটি নুলারফেরান এক্সেপশন নিক্ষেপ করবে। সুতরাং এটি সঠিকভাবে কাজ করতে, আপনি এটি করতে চাই:

if(o != null && typeof(Animal).IsAssignableFrom(o.GetType()))
    Console.WriteLine("o is an animal");

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

if(o is Animal)
    Console.WriteLine("o is an animal");

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

if(o is Animal)
    ((Animal)o).Speak();

কিন্তু এটি সিএলআর দুটি বার পর্যন্ত অবজেক্টের ধরণটি পরীক্ষা করে তোলে। isঅপারেটরটিকে সন্তুষ্ট করতে এটি একবার যাচাই করবে এবং যদি oসত্যিই Animalএটি হয় তবে আমরা কাস্টটিকে বৈধতা দেওয়ার জন্য এটি আবার চেক করব।

পরিবর্তে এটি করা আরও দক্ষ:

Animal a = o as Animal;
if(a != null)
    a.Speak();

asঅপারেটর, একটি ঢালাই যে একটি ব্যতিক্রম তা করতে ব্যর্থ হলে নিক্ষেপ করা হবে না বদলে ফেরারnull । এইভাবে, সিএলআর কেবল একবারের জন্য বস্তুর প্রকার পরীক্ষা করে এবং তারপরে আমাদের কেবল একটি নাল চেক করা দরকার যা আরও দক্ষ which

তবে সাবধান: অনেক লোক এর ফাঁদে পড়ে as। যেহেতু এটি ব্যতিক্রম ছুঁড়ে না ফেলে, কিছু লোক এটিকে "নিরাপদ" কাস্ট হিসাবে ভাবেন এবং তারা এটিকে একচেটিয়াভাবে ব্যবহার করেন, নিয়মিত কাস্টকে বাদ দেন। এটি এর মতো ত্রুটি বাড়ে:

(o as Animal).Speak();

এই ক্ষেত্রে, বিকাশকারী স্পষ্টভাবে ধরে নিচ্ছেন যে oএটি সর্বদা একটি হবে Animalএবং যতক্ষণ না তাদের অনুমান সঠিক হয় ততক্ষণ সবকিছু ঠিকঠাক কাজ করে। তবে যদি তারা ভুল হয়, তবে তারা এখানে যা শেষ করবে তা হ'ল একটি NullReferenceException। নিয়মিত castালাইয়ের সাথে তারা InvalidCastExceptionপরিবর্তে একটি উপার্জন করতে পারত যা সমস্যাটিকে আরও সঠিকভাবে চিহ্নিত করতে পারত।

কখনও কখনও, এই বাগটি খুঁজে পাওয়া শক্ত হতে পারে:

class Foo{
    readonly Animal animal;

    public Foo(object o){
        animal = o as Animal;
    }

    public void Interact(){
        animal.Speak();
    }
}

এটি অন্য ক্ষেত্রে যেখানে ডেভেলপার পরিষ্কারভাবে আশা করা হয় oএকটি হতে Animalপ্রত্যেক সময়, কিন্তু এই কন্সট্রাকটর, যেখানে স্পষ্ট নয় asঢালাই ব্যবহৃত হয়। আপনি Interactপদ্ধতিটিতে না আসা পর্যন্ত এটি স্পষ্ট নয় যেখানে animalক্ষেত্রটি ইতিবাচকভাবে নির্ধারিত হবে বলে আশা করা হচ্ছে। এই ক্ষেত্রে, আপনি কেবল একটি বিভ্রান্তিমূলক ব্যতিক্রমই শেষ করবেন না, তবে আসল ত্রুটি হওয়ার পরেও সম্ভবত এটি পরে নিক্ষেপ করা হবে না।

সংক্ষেপে:

  • আপনার যদি কেবল কোনও অবজেক্ট কোনও প্রকারের কিনা তা জানা দরকার তবে ব্যবহার করুন is

  • আপনি যদি একটি নির্দিষ্ট ধরনের একটি দৃষ্টান্ত হিসাবে একটি বস্তু চিকিত্সার জন্য প্রয়োজন, কিন্তু আপনি কি নিশ্চিত যে বস্তু টাইপ, ব্যবহারের হবে জানা না থাকলে asএবং জন্য চেক null

  • যদি আপনাকে কোনও নির্দিষ্ট ধরণের উদাহরণ হিসাবে একটি অবজেক্টের চিকিত্সা করা প্রয়োজন এবং অবজেক্টটি সেই ধরণের হয় বলে মনে করা হয়, তবে নিয়মিত castালাই ব্যবহার করুন।


এর সাথে কী দোষ হয় যদি (ও হ'ল অ্যানিমাল) ((অ্যানিমাল) ও)। স্পিক (); ? আপনি কি আরও বিশদ দিতে পারেন?
ব্যাটম্যাচি

2
@ ব্যাটম্যাসি: এটি উত্তরে - এটি দুই প্রকারের চেক তৈরি করে। প্রথমবার o is Animalযা যদি পরিবর্তনশীল ধরণ চেক করতে CLR প্রয়োজন, oএকটি হল Animal। দ্বিতীয়বার এটি পরীক্ষা করে যখন এটি বিবৃতিতে কাস্ট করে ((Animal)o).Speak()। দুবার চেক করার পরিবর্তে একবার ব্যবহার করে দেখুন as
স্যারাইড

আমি এটি একটি দুর্দান্ত ব্যাখ্যা পেয়েছি, স্পষ্ট করার জন্য ধন্যবাদ!
পল এফর্ড

16

আপনি যদি সি # 7 ব্যবহার করছেন তবে অ্যান্ড্রু হারের দুর্দান্ত উত্তরটি আপডেট করার সময় এসেছে। প্যাটার্ন ম্যাচিং একটি দুর্দান্ত শর্টকাট চালু করেছে যা আমাদের পৃথক ঘোষণাপত্র / /ালাই এবং পরীক্ষার প্রয়োজন ছাড়াই যদি বিবৃতিটির প্রসঙ্গে একটি টাইপড ভেরিয়েবল দেয় able

if (obj1 is int integerValue)
{
    integerValue++;
}

এটি এর মতো একক castালাইয়ের জন্য বেশ সুন্দরভাবে অন্তর্নিহিত দেখায় তবে আপনি যখন নিজের রুটিনে আসতে পারেন এমন অনেকগুলি সম্ভাব্য ধরণ থাকে তখন সত্যিই জ্বলে ওঠে। নীচে দু'বার কাস্টিং এড়ানোর পুরানো উপায়:

Button button = obj1 as Button;
if (button != null)
{
    // do stuff...
    return;
}
TextBox text = obj1 as TextBox;
if (text != null)
{
    // do stuff...
    return;
}
Label label = obj1 as Label;
if (label != null)
{
    // do stuff...
    return;
}
// ... and so on

এই কোডটি যথাসম্ভব সঙ্কুচিত করার আশেপাশে কাজ করার পাশাপাশি একই জিনিসটির সদৃশ ক্যাসেটগুলি এড়ানো সর্বদা আমাকে বিরক্ত করেছে। উপরেরটি নিচের সাথে প্যাটার্নের মিলের সাথে সুন্দরভাবে সংকুচিত:

switch (obj1)
{
    case Button button:
        // do stuff...
        break;
    case TextBox text:
        // do stuff...
        break;
    case Label label:
        // do stuff...
        break;
    // and so on...
}

সম্পাদনা: প্যালেকের মন্তব্য অনুসারে স্যুইচ ব্যবহারের জন্য আর নতুন পদ্ধতি আপডেট করা হয়েছে।


1
switchপ্যাটার্ন ম্যাচিংয়ের সাথে স্টেটমেন্ট ব্যবহার করা এই ক্ষেত্রে উপযুক্ত।
প্যালেক

আপনি কিভাবে এটি না সামলাতে হবে? এই নির্দিষ্ট কোড ব্লক? if (obj1 is int integerValue) { integerValue++; }
বেন ভার্টনঝেন

বেন, যদি আমি আপনার প্রশ্নটি বুঝতে পারি তবে আমি কেবলমাত্র অন্য ক্ষেত্রে পরিচালনা করার জন্য অন্য একটি বিবৃতি দেব কারণ আপনি একটি পূর্ণসংখ্য পরিবর্তনশীলতে কোনও পূর্ণসংখ্যা স্থাপন করতে পারবেন না। :)
জোয়েলসি

14

আমার সাথে Typeতুলনা করার জন্য একটি প্রপার্টি ছিল এবং ব্যবহার করতে is(যেমন my_type is _BaseTypetoLookFor) ব্যবহার করতে পারিনি , তবে আমি এগুলি ব্যবহার করতে পারি:

base_type.IsInstanceOfType(derived_object);
base_type.IsAssignableFrom(derived_type);
derived_type.IsSubClassOf(base_type);

লক্ষ্য করুন IsInstanceOfTypeএবং একই ধরণের তুলনা করার সময় IsAssignableFromফিরে trueআসুন, যেখানে ইসসব্লকসফ ফিরে আসবে false। এবং IsSubclassOfইন্টারফেসে কাজ করে না, যেখানে অন্য দুটি কাজ করে। ( এই প্রশ্ন এবং উত্তর দেখুন ।)

public class Animal {}
public interface ITrainable {}
public class Dog : Animal, ITrainable{}

Animal dog = new Dog();

typeof(Animal).IsInstanceOfType(dog);     // true
typeof(Dog).IsInstanceOfType(dog);        // true
typeof(ITrainable).IsInstanceOfType(dog); // true

typeof(Animal).IsAssignableFrom(dog.GetType());      // true
typeof(Dog).IsAssignableFrom(dog.GetType());         // true
typeof(ITrainable).IsAssignableFrom(dog.GetType()); // true

dog.GetType().IsSubclassOf(typeof(Animal));            // true
dog.GetType().IsSubclassOf(typeof(Dog));               // false
dog.GetType().IsSubclassOf(typeof(ITrainable)); // false

9

আমি পছন্দ হয়

যে বলেন, যদি আপনি ব্যবহার করছেন হয় , আপনি সম্ভবত করছি না সঠিকভাবে উত্তরাধিকার ব্যবহার করে।

অনুমান যে ব্যক্তিৰ সত্ত্বা, এবং সেই প্রাণীৰ সত্ত্বা। ফিড হ'ল সত্ত্বার একটি ভার্চুয়াল পদ্ধতি (নীলকে খুশি করতে)

class Person
{
  // A Person should be able to Feed
  // another Entity, but they way he feeds
  // each is different
  public override void Feed( Entity e )
  {
    if( e is Person )
    {
      // feed me
    }
    else if( e is Animal )
    {
      // ruff
    }
  }
}

বরং

class Person
{
  public override void Feed( Person p )
  {
    // feed the person
  }
  public override void Feed( Animal a )
  {
    // feed the animal
  }
}

1
সত্য, আমি জেনেছি না যে প্রাক্তন কখনই প্রাণী থেকে প্রাপ্ত।
জেসনহ

3
আধুনিককৃতরা সত্যই উত্তরাধিকার ব্যবহার করছে না। ফু হ'ল ব্যক্তি এবং প্রাণীগুলিতে ওভাররাইড হওয়া সত্তার ভার্চুয়াল পদ্ধতি হওয়া উচিত।
নীল উইলিয়ামস

2
@ বোবোবো আমার ধারণা আপনি "ওভারলোডিং" বলতে চান, "উত্তরাধিকার" নয়।
এলসি

@ এলসি: না, আমি উত্তরাধিকার বলতে চাইছি। প্রথম উদাহরণটি বিভিন্ন ধরণের আচরণ পেতে এক ধরণের ভুল উপায় (ব্যবহার করা হয় )। দ্বিতীয় উদাহরণ হ'ল ওভারলোডিং ব্যবহার করে, তবে এর ব্যবহার এড়ানো হয়
বোবোবোবো

1
উদাহরণ সহ সমস্যাটি হ'ল এটি স্কেল হবে না। যদি আপনি খাওয়ার জন্য প্রয়োজনীয় নতুন সত্ত্বা যুক্ত করেন (উদাহরণস্বরূপ একটি পোকামাকড় বা একটি দানব) আপনাকে সত্তা শ্রেণিতে একটি নতুন পদ্ধতি যুক্ত করতে হবে এবং তারপরে এটি সাবস্ক্লাসে ওভাররাইড করা হবে যা এটি খাওয়ায়। এটি (সত্তাটি এক্স) অন্যথায় (সত্তাটি হ'ল) ​​যদি এটি তালিকার চেয়ে বেশি পছন্দসই নয় ... এটি এলএসপি এবং ওসিপি লঙ্ঘন করে, উত্তরাধিকার সম্ভবত সমস্যার সর্বোত্তম সমাধান নয়। প্রতিনিধিদের কিছু ফর্ম সম্ভবত পছন্দ করা হবে।
উড়িত

5

আমি বিশ্বাস করি যে শেষটি উত্তরাধিকারের দিকেও লক্ষ্য করে (যেমন কুকুরটি প্রাণী == সত্য), যা বেশিরভাগ ক্ষেত্রেই ভাল।


2

এটি আমি কী করছি তার উপর নির্ভর করে। আমার যদি একটি বুল মান প্রয়োজন (বলুন, আমি কোন পূর্বে কাস্ট করব কিনা তা নির্ধারণ করতে), আমি ব্যবহার করব is। আমার যদি আসলে কোনও কারণে টাইপটির প্রয়োজন হয় (বলুন, অন্য কোনও পদ্ধতিতে পাস করার জন্য) আমি ব্যবহার করব GetType()


1
ভাল যুক্তি. আমি উল্লেখ করতে ভুলে গেছি যে বেশ কয়েকটি উত্তর দেখার পরে আমি এই প্রশ্নে পৌঁছেছি যা কোনও প্রকার পরীক্ষা করার জন্য যদি একটি বিবৃতি ব্যবহার করে।
জেসনহ

0

শেষটি হ'ল ক্লিনার, আরও সুস্পষ্ট এবং সাব-টাইপগুলি পরীক্ষা করে। অন্যরা পলিমারফিজম পরীক্ষা করে না।


0

এক প্রকারের জন্য System.Type অবজেক্টটি ব্যবহার করতে ব্যবহৃত হয়। একটি টাইফফ এক্সপ্রেশন নিম্নলিখিত ফর্মটি গ্রহণ করে:

System.Type type = typeof(int);

Example:

    public class ExampleClass
    {
       public int sampleMember;
       public void SampleMethod() {}

       static void Main()
       {
          Type t = typeof(ExampleClass);
          // Alternatively, you could use
          // ExampleClass obj = new ExampleClass();
          // Type t = obj.GetType();

          Console.WriteLine("Methods:");
          System.Reflection.MethodInfo[] methodInfo = t.GetMethods();

          foreach (System.Reflection.MethodInfo mInfo in methodInfo)
             Console.WriteLine(mInfo.ToString());

          Console.WriteLine("Members:");
          System.Reflection.MemberInfo[] memberInfo = t.GetMembers();

          foreach (System.Reflection.MemberInfo mInfo in memberInfo)
             Console.WriteLine(mInfo.ToString());
       }
    }
    /*
     Output:
        Methods:
        Void SampleMethod()
        System.String ToString()
        Boolean Equals(System.Object)
        Int32 GetHashCode()
        System.Type GetType()
        Members:
        Void SampleMethod()
        System.String ToString()
        Boolean Equals(System.Object)
        Int32 GetHashCode()
        System.Type GetType()
        Void .ctor()
        Int32 sampleMember
    */

এই নমুনাটি সংখ্যার গণনার ফলাফল ধারণ করতে ব্যবহৃত ধরণ নির্ধারণ করতে গেটটাইপ পদ্ধতি ব্যবহার করে। এটি ফলাফল প্রাপ্ত সংখ্যার স্টোরেজ প্রয়োজনীয়তার উপর নির্ভর করে।

    class GetTypeTest
    {
        static void Main()
        {
            int radius = 3;
            Console.WriteLine("Area = {0}", radius * radius * Math.PI);
            Console.WriteLine("The type is {0}",
                              (radius * radius * Math.PI).GetType()
            );
        }
    }
    /*
    Output:
    Area = 28.2743338823081
    The type is System.Double
    */

-4
if (c is UserControl) c.Enabled = enable;

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

আপনার উত্তর প্রশ্নের সাথে সম্পর্কিত নয়।
Menxin

-5

আপনি সি # তে "টাইপফ ()" অপারেটর ব্যবহার করতে পারেন তবে আপনাকে সিস্টেম.আইও ব্যবহার করে নেমস্পেসে কল করতে হবে; আপনি যদি কোনও ধরণের জন্য যাচাই করতে চান তবে আপনাকে অবশ্যই "is" কীওয়ার্ডটি ব্যবহার করতে হবে।


7
typeofএকটি নেমস্পেসে সংজ্ঞায়িত করা হয়নি, এটি একটি কীওয়ার্ড। System.IOএর সাথে কিছু করার নেই।
আর্টুরো টরেস সানচেজ

-5

পারফরম্যান্স পরীক্ষার টাইপ () বনাম গেটটাইপ ():

using System;
namespace ConsoleApplication1
    {
    class Program
    {
        enum TestEnum { E1, E2, E3 }
        static void Main(string[] args)
        {
            {
                var start = DateTime.UtcNow;
                for (var i = 0; i < 1000000000; i++)
                    Test1(TestEnum.E2);
                Console.WriteLine(DateTime.UtcNow - start);
            }
            {
                var start = DateTime.UtcNow;
                for (var i = 0; i < 1000000000; i++)
                    Test2(TestEnum.E2);
                Console.WriteLine(DateTime.UtcNow - start);
            }
            Console.ReadLine();
        }
        static Type Test1<T>(T value) => typeof(T);
        static Type Test2(object value) => value.GetType();
    }
}

ডিবাগ মোডে ফলাফল:

00:00:08.4096636
00:00:10.8570657

রিলিজ মোডে ফলাফল:

00:00:02.3799048
00:00:07.1797128

1
পারফরম্যান্স পদক্ষেপের জন্য কেউ ডেটটাইম ব্যবহার করতে হবে না t আপনার কোড সহ তবে স্টপওয়াচ ক্লাসের সাথে আমি ডিবাগ মোডের জন্য অবিচ্ছিন্ন ফলাফল পেয়েছি। UseTypeOf: 00: 00: 14.5074469 ইউজগেটটাইপ: 00: 00: 10.5799534। রিলিজ মোডটি প্রত্যাশার মতো একই
আলেক্সি শ্যাচারবাক

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

1
এটি সাধারণভাবে খারাপ অভ্যাস, আপনার বিশেষ ক্ষেত্রে নয়।
আলেক্সি শ্যাচারবাক

4
কোড লাইনের @AlexanderVasilyev পরিমাণ কিছু করতে একটি আর্গুমেন্ট হিসাবে কখনও ব্যবহার করা উচিত documentedly বিভ্রান্তিকর। হিসাবে দেখা msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx , DateTimeযদি আপনি নিচে বার নিয়ে চিন্তিত থাকেন ব্যবহার করা উচিত নয় 100 মিঃসে , যেহেতু এটি অপারেটিং সিস্টেম এর সময়সীমার ব্যবহার করে। তুলনামূলকভাবে Stopwatch, যা প্রসেসর ব্যবহার করে ' Tick, DateTimeউইন 7-এ একটি দ্বারা ব্যবহৃত রেজোলিউশন হুপিং 15 মিমি।
এরিক উ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.