c# - करन - हिंदी में कैसे लिखा जाता है




टाइपिंग टाइप करें: टाइपऑफ, गेट टाइप, या है? (10)

सिस्टम को प्राप्त करने के लिए प्रयुक्त होता है। एक प्रकार के लिए ऑब्जेक्ट टाइप करें। एक प्रकार की अभिव्यक्ति निम्न प्रपत्र लेती है:

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
    */

यह नमूना उस संख्या को निर्धारित करने के लिए GetType विधि का उपयोग करता है जिसका उपयोग संख्यात्मक गणना के परिणाम को करने के लिए किया जाता है। यह परिणामी संख्या की भंडारण आवश्यकताओं पर निर्भर करता है।

    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
    */

मैंने देखा है कि कई लोग निम्नलिखित कोड का उपयोग करते हैं:

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

निजी तौर पर, मुझे लगता है कि आखिरी वाला सबसे साफ है, लेकिन क्या मुझे कुछ याद आ रही है? कौन सा सबसे अच्छा उपयोग करने के लिए है, या यह व्यक्तिगत वरीयता है?


आखिरी वाला क्लीनर, अधिक स्पष्ट है, और उपप्रकारों के लिए भी जांच करता है। अन्य polymorphism की जांच नहीं करते हैं।


जब आप संकलन समय पर प्रकार प्राप्त करना चाहते हैं तो typeof उपयोग करें। जब आप निष्पादन समय पर प्रकार प्राप्त करना चाहते हैं तो GetType उपयोग करें। उपयोग करने के लिए शायद ही कभी कोई भी मामला is क्योंकि यह एक कास्ट करता है और, ज्यादातर मामलों में, आप वैसे भी चर कास्टिंग समाप्त करते हैं।

एक चौथा विकल्प है जिसे आपने नहीं माना है (विशेष रूप से यदि आप किसी ऑब्जेक्ट को उस प्रकार के लिए डालने जा रहे हैं जो आपको मिलती है); इसका उपयोग करना as

Foo foo = obj as Foo;

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

यह केवल एक कास्ट का उपयोग करता है जबकि यह दृष्टिकोण:

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

दो की आवश्यकता है।


प्रदर्शन परीक्षण प्रकार () बनाम GetType ():

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

मेरा मानना ​​है कि अंतिम व्यक्ति भी विरासत को देखता है (उदाहरण के लिए कुत्ता पशु == सत्य है), जो ज्यादातर मामलों में बेहतर होता है।


मेरे पास तुलना करने के लिए Type प्रॉपर्टी थी और इसका उपयोग नहीं किया जा सकता था (जैसे my_type is _BaseTypetoLookFor ), लेकिन मैं इनका उपयोग कर सकता था:

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

ध्यान दें कि IsInstanceOfType और IsAssignableFrom उसी प्रकार की तुलना करते समय true लौटने से, जहां IsSubClassOf 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

यह इस बात पर निर्भर करता है कि मैं क्या कर रहा हूं। अगर मुझे बूल वैल्यू की आवश्यकता है (कहें, यह निर्धारित करने के लिए कि क्या मैं एक int में डाल दूंगा), मैं इसका उपयोग करूंगा। अगर मुझे वास्तव में किसी कारण के लिए प्रकार की आवश्यकता है (कहें, किसी अन्य विधि को पास करने के लिए) मैं GetType() उपयोग करूंगा।


सभी अलग हैं।

  • typeof एक प्रकार का नाम लेता है (जिसे आप संकलन समय पर निर्दिष्ट करते हैं)।
  • GetType को रनटाइम प्रकार का उदाहरण मिलता है।
  • विरासत वृक्ष में एक उदाहरण है अगर सच है।

उदाहरण

class Animal { } 
class Dog : Animal { }

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

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

typeof(T) बारे में क्या? क्या यह संकलन समय पर भी हल किया गया है?

हाँ। टी अभिव्यक्ति का प्रकार हमेशा होता है। याद रखें, एक सामान्य विधि मूल रूप से उपयुक्त प्रकार के साथ विधियों का एक पूरा समूह है। उदाहरण:

string Foo<T>(T object) { 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"

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 नहीं। यदि आप Type क्लास की IsAssignableFrom विधि का उपयोग करते हैं, तो आप यह काम कर सकते हैं।

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

हालांकि, यह तकनीक अभी भी एक बड़ी समस्या छोड़ देती है। यदि आपका चर शून्य है, तो GetType() कॉल एक NullReferenceException फेंक देगा। तो इसे सही तरीके से काम करने के लिए, आप करेंगे:

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

इसके साथ, आपके पास कीवर्ड का समतुल्य व्यवहार is । इसलिए, यदि यह वह व्यवहार है जिसे आप चाहते हैं, तो आपको कीवर्ड का उपयोग करना चाहिए, जो अधिक पठनीय और अधिक कुशल है।

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

ज्यादातर मामलों में, हालांकि, कीवर्ड अभी भी वही नहीं है जो आप वास्तव में चाहते हैं, क्योंकि यह आमतौर पर यह जानने के लिए पर्याप्त नहीं है कि एक वस्तु एक निश्चित प्रकार का है। आमतौर पर, आप उस वस्तु का उस उदाहरण के उदाहरण के रूप में वास्तव में उपयोग करना चाहते हैं, जिसके लिए इसे भी कास्टिंग करना आवश्यक है। और इसलिए आप स्वयं को इस तरह कोड लिख सकते हैं:

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

लेकिन इससे सीएलआर ऑब्जेक्ट के प्रकार को दो बार जांचता है। ऑपरेटर को संतुष्ट करने के लिए यह एक बार जांच करेगा, और यदि o वास्तव में एक Animal , तो हम इसे कास्ट को सत्यापित करने के लिए फिर से जांचते हैं।

इसके बजाए ऐसा करना अधिक कुशल है:

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

ऑपरेटर के as में एक कलाकार है जो अपवाद नहीं फेंकता है, अगर यह विफल रहता है, तो बदले में वापस आ जाता है। इस तरह, सीएलआर ऑब्जेक्ट के प्रकार को सिर्फ एक बार जांचता है, और उसके बाद, हमें केवल एक शून्य जांच करने की आवश्यकता होती है, जो अधिक कुशल है।

लेकिन सावधान रहें: बहुत से लोग एक जाल में आते हैं। चूंकि यह अपवाद नहीं फेंकता है, कुछ लोग इसे "सुरक्षित" कलाकार के रूप में सोचते हैं, और वे इसे नियमित रूप से चौंकाने वाले नियमित रूप से उपयोग करते हैं। इससे इस तरह की त्रुटियां होती हैं:

(o as Animal).Speak();

इस मामले में, डेवलपर स्पष्ट रूप से मान रहा है कि o हमेशा एक Animal , और जब तक उनकी धारणा सही है, सबकुछ ठीक काम करता है। लेकिन अगर वे गलत हैं, तो वे यहां क्या खत्म करते हैं वह एक NullReferenceException । एक नियमित कलाकार के साथ, वे इसके बजाय एक InvalidCastException प्राप्त कर लेते थे, जो समस्या को और अधिक सही ढंग से पहचाना होता।

कभी-कभी, यह बग ढूंढना मुश्किल हो सकता है:

class Foo{
    readonly Animal animal;

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

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

यह एक और मामला है जहां डेवलपर स्पष्ट रूप से हर समय एक Animal होने की उम्मीद कर रहा है, लेकिन यह कन्स्ट्रक्टर में स्पष्ट नहीं है, जहां कास्ट का उपयोग किया जाता है। यह तब तक स्पष्ट नहीं है जब तक कि आप Interact विधि तक नहीं पहुंच जाते, जहां animal क्षेत्र को सकारात्मक रूप से असाइन किया जाने की उम्मीद है। इस मामले में, न केवल आप एक भ्रामक अपवाद के साथ समाप्त होते हैं, लेकिन वास्तविक त्रुटि होने के बाद संभावित रूप से बाद में इसे फेंक दिया नहीं जाता है।

संक्षेप में:

  • यदि आपको केवल यह जानने की ज़रूरत है कि कोई वस्तु किसी प्रकार का is या नहीं, तो उपयोग करें।

  • यदि आपको किसी ऑब्जेक्ट को किसी निश्चित प्रकार के उदाहरण के रूप में इलाज करने की आवश्यकता है, लेकिन आप यह सुनिश्चित करने के लिए नहीं जानते कि ऑब्जेक्ट उस प्रकार का होगा, null as उपयोग करें और जांचें।

  • यदि आपको किसी ऑब्जेक्ट को किसी निश्चित प्रकार के उदाहरण के रूप में इलाज करने की आवश्यकता है, और ऑब्जेक्ट उस प्रकार का होना चाहिए, तो नियमित कास्ट का उपयोग करें।


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




c#