Verifique se a instância é de um tipo


181

Use isso para verificar se cé uma instância de TForm.

c.GetType().Name.CompareTo("TForm") == 0

Existe uma maneira mais segura de fazer isso além de usar stringum parâmetro CompareTo()?


20
Eu certamente espero que você também não faça isso em Java. Java instanceofe C # issão maneiras muito melhores de fazê-lo.
Powerlord

Respostas:


410

As respostas diferentes aqui têm dois significados diferentes.

Se você deseja verificar se uma instância é de um tipo exato ,

if (c.GetType() == typeof(TForm))

é o caminho a percorrer.

Se você quiser saber se cé uma instância TForm ou subclasse , use is/ as:

if (c is TForm)

ou

TForm form = c as TForm;
if (form != null)

Vale a pena ficar claro em sua mente sobre qual desses comportamentos você realmente deseja.


7
Uma pequena nota: use "is" se você não quiser usar o resultado do elenco e use "as" se desejar.
Aviram Fireberger

14
Com o C # 7 você pode combinar ise ascom a correspondência de padrões:if (x is TForm tf) {…
Richard

39
if(c is TFrom)
{
   // Do Stuff
}

ou se você planeja usar ccomo a TForm, use o seguinte exemplo:

var tForm = c as TForm;
if(tForm != null)
{
   // c is of type TForm
}

O segundo exemplo só precisa verificar se cé do tipo TFormuma vez. Onde você verifica se cé do tipo e TFormdepois o lança, o CLR passa por uma verificação extra. Aqui está uma referência .

Edit: Roubado de Jon Skeet

Se você quiser ter certeza de que cé TForme não uma classe herdada TForm, use

if(c.GetType() == typeof(TForm))
{
   // Do stuff cause c is of type TForm and nothing else
}


10

Além disso, um pouco na mesma linha

Type.IsAssignableFrom(Type c)

"True se c e o tipo atual representam o mesmo tipo, ou se o tipo atual está na hierarquia de herança de c, ou se o tipo atual é uma interface que c implementa, ou se c é um parâmetro de tipo genérico e o tipo atual representa uma das restrições de c. "

A partir daqui: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx


este também é o meu favorito. typeof(Class).IsAssignableFrom(object.getType())semelhante ao instanceofoperador Java .
SkidRunner 7/11

Ele fornece false se eles não estão no mesmo ramo da hierarquia de herança, mas existe um operador de conversão?
Paul Stelian

Boa pergunta @PaulStelian. Não tenho certeza do que estou pensando, mas meu palpite seria que isso retornaria falso nessa situação. Esse seria pelo menos o meu comportamento esperado. Possivelmente, se houver uma conversão implícita, ela poderá retornar verdadeira, mas isso seria estranho.
Brad Cunningham

Alguém que tenha o Visual Studio instalado para experimentá-lo?
Paul Stelian

1
@PaulStelian - retorna false. Isso pode ser visto seguindo o link do documento e observando que não há menção de conversões. Outra maneira de pensar é que T1.IsAssignableFrom(T2)retorna trueem situações em que o asoperador retorna um valor não nulo, dadas as instâncias desses tipos.
Home

9

Um pouco mais compacto que as outras respostas, se você quiser usar c como um TForm:

if(c is TForm form){
    form.DoStuff();
}


2

Como outros já mencionaram, a palavra-chave "é". No entanto, se mais tarde você o converter nesse tipo, por exemplo.

TForm t = (TForm)c;

Então você deve usar a palavra-chave "as".

por exemplo TForm t = c as TForm.

Então você pode conferir

if(t != null)
{
 // put TForm specific stuff here
}

Não combine como é porque é uma verificação duplicada.



-1
bool isValid = c.GetType() == typeof(TForm) ? true : false;

ou mais simples

bool isValid = c.GetType() == typeof(TForm);

IMHO: Eu evitaria uma compaixão direta (ie. ==). Em objetos ou linguagens orientadas que suportam herança, a menos que você saiba que seu tipo específico nunca será herdado de, por exemplo, uma sealedclasse. Além disso: o uso de um operador ternário retornando valores booleanos (estáticos / constantes) me incomoda, eu ficaria menos incomodado se fosse uma switchdeclaração.
SkidRunner 7/11
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.