Below my code. It returns exception “InvalidCastException”. And main question is – why?
What is wrong?
Error text:
Unable to cast object of type
‘WhereSelectListIterator`2[Monopolowy_beta.Gracz,Monopolowy_beta.Gracz]’
to type ‘Monopolowy_beta.Gracz’.
namespace Monopolowy_beta
{
class Program
{
static void Main(string[] args)
{
List<Gracz> lista = new List<Gracz> { };
Gracz g1 = new Gracz();
Gracz g2 = new Gracz();
Gracz g3 = new Gracz();
g2.Id = 3;
lista.Add(g1);
lista.Add(g2);
lista.Add(g3);
g1 = GraczeTools.UstawAktywnegoGracza(lista, 3);
Console.ReadKey();
}
}
}
Error in these lines:
var docelowy = from item in listagraczy where (item.Id==ID && item.czyAktywny == true) select listagraczy[listagraczy.IndexOf(item) + 1];
gracz = (Gracz)docelowy;
namespace Monopolowy_beta
{
static class GraczeTools
{
public static Gracz UstawAktywnegoGracza(List<Gracz> listagraczy, int ID)
{
Gracz gracz = new Gracz();
if (ID == 4){
var docelowy = from item in listagraczy where (item.czyAktywny == true && item.Id == 3) select listagraczy[1];
gracz = (Gracz)docelowy;
}
if (ID != 4){
var docelowy = from item in listagraczy where (item.Id==ID && item.czyAktywny == true) select listagraczy[listagraczy.IndexOf(item) + 1];
gracz = (Gracz)docelowy;
}
return gracz;
}
}
}
Let’s examine this query. It finds all items which satisfy condition (yes, it will return sequence, not single item) and for each such item, it returns.. second element of
listagraczylist. Yes, you don’t have items, which matched your condition.I think you should select
iteminstead (this a range variable of your query), and applyFirstOrDefaultto result, because by default query will returnIEnumerable<Gracz>result.Which is better to write with fluent API:
Also you can use boolean values directly in conditions (i.e.
item.czyAktywnyinstead ofitem.czyAktywny == true).After little refactoring your method should look like
How it works:
You have two conditional blocks in your method
if (ID == 4)andif (ID != 4)(which is actuallyif ... else. Difference is that you are filtering sequence by one more condition in first case –item.czyAktywnyshould be true. In second case this property does not matter. So, you can add one filtering condition instead(ID != 4 || item.czyAktywny)– czyAktywny will be verified only if ID equal to 4. Also you don’t need to create newGraczobject in your method, because you anyway return one from passed list.