Como um exemplo simplificado do meu problema, tenho um array de ISomeType
, e quero fazer um loop sobre todos os elementos naquele array que são realmente MyType
, mas estou recebendo avisos IDE0220 "Add explicit cast in foreach loop" que não acho que se apliquem. Aqui está um exemplo de código:
public interface ISomeType {
void DoThing();
}
public class MyType: ISomeType {
void DoThing() { /* do something */ }
void DoMyTypeThing() { /* do something specific to MyType */ }
}
public class YourType: ISomeType {
void DoThing() { /* do something */ }
void DoMyTypeThing() { /* do something specific to MyType */ }
}
ISomeType[] maybeMyTypes = [new MyType()];
// I get the error on this line because I cast the element into `MyType`
foreach (MyType foobar in maybeMyTypes.Where(i => i.GetType() == typeof(MyType))) {
// use the MyType methods availbale on foobar
}
O compilador reclama que ele converte implicitamente os elementos de maybeFooBars
em MyType
, e que isso pode falhar em tempo de execução, então devo ser explícito sobre a conversão:
// Code with violations. var list = new List<object>(); foreach (string item in list) { } // Fixed code. var list = new List<object>(); foreach (string item in list.Cast<string>())
Meu código poderia realmente falhar em tempo de execução, já que estou verificando o tipo e apenas fazendo cast implicitamente se o tipo estiver correto? Ou o compilador C# não é inteligente o suficiente para ver que eu me protegi contra os tipos estarem incorretos?
.Where(i => i.GetType() == typeof(MyType))
não dirá ao compilador que você está lidando apenas comMyType
membros. Para isso, você vai quererOfType
em vez disso. Então você vai usá-lo comoGetType
é uma operação de tempo de execução , não ajudará o compilador a inferir o tipo correto. Então, para o compilador , suaWhere
instrução retorna apenas uma lista deISomeType
. Então você recebe o aviso de que precisa converter o tipo para o derivado.Além disso, sua instrução - selecionará
Where
apenas os itens que correspondem à condição. Ela não transformará seus itens para o tipo desejado. apenas retorna exatamente o mesmo tipo de coleção que recebeu como parâmetro. Então, se a coleção de entrada para for do tipo , isso se aplica à saída também.Where
Where
ISomeType
Então, afinal, o que você quer é selecionar esses objetos cujo tipo é o desejado e convertê-los apropriadamente. Então, use
OfType
em vez disso, que é semelhante a executar umas
-cast e retornar aqueles cujo valor de retorno não énull
. Alternativamente, você pode usarCast<MyObject>
, no entanto, isso lhe dará umInvalidCastException
se houver algum elemento que não seja desse tipo.