I have a Dictionary in which Value is a class, that class contains about 15 variables.
I was wondering whether it was possible to create a class that would return entries that match optional parameters of that class, in this fashion:
class GetPlayer {
public string name;
public float health;
public int level;
}
public void GetPlayer(string name = "", float? health = "", int? level = "") {
// return SomeLINQHere.WhereVariableMatchIfVariableIsNotNull;
}
And return entries that have their value equal to the parameter, if param is not null.
If param is null, ignore the parameter.
I do know structure of the class beforehand.
I would do it manually, but I have a problem, what if I’m looking for an entry’s variable that has a null value and I pass a null parameter?
Is there a way to get this to work?
Edit: I would like to have all items that match the requirements, not the first encounter only.
from var p in AllPlayers
where (name == null || name.Value == p.name)
&& (health == null || health.Value == p.health)
&& (level == null || level.Value == p.level)
select ...
However, if you need to support both “I don’t care about this parameter” and “I specifically want this parameter to have a value of null”, then you’ll need to work out a way of encoding the former other than simply setting the search value to null.
Are there any obscene values I can set in parameter declaration as a default value that would (almost) never be used?
Then I could treat it as if it’s null and tell LINQ to ignore this variable if it has that crazy value.
Special characters? Anything?
Also you wrote select ..., what do I write behind it?
Hmmm: Cannot convert initializer type "System.Collections.Generic.IEnumerable<Player>" to target type "System.Collections.Generic.List<Player>"
in:
List<Player> foundPlayers =
from Player testPlayer in AllPlayers
where (name == null || name.Value == testPlayer.name)
&& (health == null || health.Value == testPlayer.health)
&& (level == null || level.Value == testPlayer.level)
select testPlayer;
return foundPlayers;
Apparently foundPlayers needs to be a var (because I’m a lazy programmer who won’t type out the entirety), and the return result needs to be made ToList();. Apparently LINQ doesn’t return List it returns IEnumerator.
After “select” you put whatever you want it to return. If you want to return the entire player, then you’ve got it right. But hypothetically, if you only wanted the name of the player and not the whole player object, you could write something like “select testPlayer.name”
The return value of an entire linq query will always be IEnumerable, where “something” is the type of whatever you wrote in the “select” clause. If you need a List, you can write .ToList(); but that forces extra memory allocation, so generally only do that if it matters.
Whether there are any values that will “almost never be used” depends entirely on your data set.
If you can’t figure out anything that’s safe to use, then you can instead write separate functions with different argument lists.