c# case - Tipo di controllo: typeof, GetType o is?




7 Answers

Tutti sono diversi

  • typeof accetta un nome di tipo (che si specifica al momento della compilazione).
  • GetType ottiene il tipo di runtime di un'istanza.
  • is restituisce true se un'istanza si trova nell'albero di ereditarietà.

Esempio

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);

Che ne dici di typeof(T) ? È risolto anche in fase di compilazione?

Sì. T è sempre ciò che è il tipo di espressione. Ricorda, un metodo generico è fondamentalmente un insieme di metodi con il tipo appropriato. Esempio:

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"
textbox object

Ho visto molte persone usare il seguente codice:

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

Ma so che potresti anche fare questo:

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

O questo:

if (obj1 is int)
    // Some code here

Personalmente, sento che l'ultimo è il più pulito, ma c'è qualcosa che mi manca? Qual è il migliore da usare, o è una preferenza personale?




1.

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

Questo è illegale, perché typeof funziona solo sui tipi, non sulle variabili. Presumo che obj1 sia una variabile. Quindi, in questo modo typeof è statico e fa il suo lavoro in fase di compilazione anziché in runtime.

2.

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

Questo è vero se obj1 è esattamente di tipo int. Se obj1 deriva da int, la condizione if sarà falsa.

3.

if (obj1 is int)

Questo è vero se obj1 è un int, o se deriva da una classe chiamata int, o se implementa un'interfaccia chiamata int.




Avevo una proprietà Type da confrontare e non poteva usare is (come my_type is _BaseTypetoLookFor ), ma potrei usare questi:

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

Si noti che IsInstanceOfType e IsAssignableFrom restituiscono true quando si confrontano gli stessi tipi, in cui IsSubClassOf restituirà false . E IsSubclassOf non funziona sulle interfacce, dove le altre due lo fanno. (Vedi anche questa domanda e risposta .)

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



Preferisco lo è

Detto questo, se stai usando, probabilmente non usi correttamente l'ereditarietà.

Supponi che Person: Entity e that Animal: Entity. Feed è un metodo virtuale in Entity (per rendere Neil felice)

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
    }
  }
}

Piuttosto

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



Dipende da cosa sto facendo. Se ho bisogno di un valore di bool (per esempio, per determinare se scriverò a un int), userò is . Se effettivamente ho bisogno del tipo per qualche motivo (per esempio, per passare ad un altro metodo) userò GetType() .




Utilizzato per ottenere l'oggetto System.Type per un tipo. Un tipo di espressione assume la seguente forma:

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

Questo esempio utilizza il metodo GetType per determinare il tipo utilizzato per contenere il risultato di un calcolo numerico. Questo dipende dai requisiti di archiviazione del numero risultante.

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



È possibile utilizzare l'operatore "typeof ()" in C # ma è necessario chiamare lo spazio dei nomi utilizzando System.IO; È necessario utilizzare la parola chiave "è" se si desidera verificare un tipo.




Related


Tags

c#