Será reflexão em C#
oferta uma maneira de determinar se alguns dados System.Type
modelos tipo algum interface?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
c#
reflection
interface
Yippie-Ki-Yay
fonte
fonte
IsAssignableFrom
trás. Vou comGetInterfaces
agora: pIsAssignableFrom(t1)
variante é cerca de 3x mais rápida que aGetInterfaces().Contains(t2)
contraparte no meu código.typeof(MyType).GetInterface(nameof(IMyInterface)) != null
um melhor tipo de segurança e refatoração.Use
Type.IsAssignableFrom
:fonte
ou
fonte
someclass is IMyInterface
porque isso não envolve o custo da reflexão. Portanto, embora não esteja errado, não é a maneira ideal de fazê-lo.is
verifica nas duas direções da hierarquia de herança, enquantoIsAssignableFrom
apenas verifica para cima. Além disso, se você tiver uma instância de um objeto, deverá chamarIsInstanceOfType
(que também olha apenas para cima).Eu acho que este é o lançamento correto, por três razões:
fonte
Eu apenas fiz:
Eu gostaria de ter dito
where I : interface
, masinterface
não é uma opção genérica de restrição de parâmetros.class
é o mais próximo possível.Uso:
Acabei de dizer
Implements
porque é mais intuitivo. Eu sempre souIsAssignableFrom
enganado.fonte
return typeof(I).IsInterface && typeof(I).IsAssignableFrom(source);
para retornar false em qualquer uso 'incorreto' do método, ou seja; usando-o com um tipo de classe em vez de um tipo de interface, lance alternativamente uma exceção se o parâmetro-tipo não for uma interface. Embora você poderia argumentar que uma classe derivada 'implementos' É pai ...Modificando a resposta de Jeff para obter o desempenho ideal (graças ao teste de desempenho de Pierre Arnaud):
Para encontrar todos os tipos que implementam uma interface em um dado
Assembly
:fonte
Como alguém já mencionou: Benjamin 10 / abr / 13 às 22:21 "
Bem, outra maneira é apenas criar um método de extensão curto que atenda, até certo ponto, à maneira "mais usual" de pensar (e concordou que essa é uma escolha pessoal muito pequena para torná-la um pouco "mais natural" com base nas preferências de alguém ):
E por que não ficar um pouco mais genérico (bem, não tenho certeza se é realmente tão interessante, bem, eu suponho que estou passando outra pitada de açúcar 'sintaxe'):
Eu acho que pode ser muito mais natural assim, mas mais uma vez apenas uma questão de opiniões muito pessoais:
fonte
Boolean
=>bool
(não sei por que costumava ter algumas regras "sofisticadas" de codificação quando era mais jovem).Se você tem um tipo ou uma instância, pode verificar facilmente se eles suportam uma interface específica.
Para testar se um objeto implementa uma certa interface:
Para testar se um tipo implementa uma certa interface:
Se você obteve um objeto genérico e deseja fazer uma conversão, bem como verificar se a interface para a qual você lança está implementada, o código é:
fonte
IsAssignableFrom
agora é movido paraTypeInfo
:fonte
Qualquer pessoa que procure por isso pode achar útil o seguinte método de extensão:
testes de unidade:
fonte
A respeito
?
fonte
A respeito
fonte
Uma resposta correta é
Contudo,
pode retornar um resultado errado, como o seguinte código mostra com string e IConvertible:
Resultados:
fonte
IsAssignableFrom
. Assim como Benjamin e Ehouarn avisam.Observe que se você tiver uma interface genérica
IMyInterface<T>
, ela sempre retornaráfalse
:Isso também não funciona:
No entanto, se
MyType
implementarIMyInterface<MyType>
isso funciona e retornatrue
:No entanto, você provavelmente não saberá o parâmetro type
T
em tempo de execução . Uma solução um pouco hacky é:A solução de Jeff é um pouco menos invasiva:
Aqui está um método de extensão
Type
que funciona para qualquer caso:(Observe que o acima usa linq, que é provavelmente mais lento que um loop.)
Você pode então fazer:
fonte