C# List<T>.Find

Started by
33 comments, last by Anthracis 11 years, 7 months ago

Yes, what I meant with the "First" LINQ extension was actually the method CALLED First:


var y = myList.First(x => x.ID == id);

or

var y = myList.FirstOrDefault(x => x.ID == id);

This is getting weird... Have you done a clean solution and then a rebuild solution?

This just gets stranger :


EngineObject elObjectO = objectList.First( x => x.ID == objectId );


Works perfectly, as does :


EngineObject elObjectO = objectList.FirstOrDefault( x => x.ID == objectId );


Just not :


EngineObject elObjectO = objectList.Find( x => x.ID == objectId );


I thought it might be something to do with EngineObject being abstract... but no.

And yeah, I've cleaned my solution and rebuilt... I also reboot my PC smile.png
Advertisement

Soo... I tried pasting the code you have supplied in a new XNA project in Visual Studio 2010. Compiles fine. Then I did the same in VS2008. No errors there either. It seems like the errors is somewhere else in the code. What compiler are you using? If you don't mind, maybe you can zip the project and attach it to a post here so we can take a look smile.png

I'd be happy to link to upload my engine project, but don't have a premium membership. I'm using VS2010.
The "Find" function is a member of the List<T> class, the other functions are LINQ statements. These have different signatures (Find takes a Predicate<T>, where the LINQ functions take Func<T, bool>) and are implemented in completely different libraries / namespaces. This must be the root of the problem, but I don't have a compiler handy to investigate. When in doubt and using LINQ, hover over the function to see which signature it is trying to use and then find examples to match that (for instance look to an OLDER, .NET 2.0 example for using Find before LINQ instead of a newer 3.5 or 4.0 example).

I'm also not sure if the problem will be in some assumption the Predicate version makes about your class "EngineObject" or if it will be a simple issue with the syntax having to be slightly different. Good Luck.

The "Find" function is a member of the List<T> class, the other functions are LINQ statements. These have different signatures (Find takes a Predicate<T>, where the LINQ functions take Func<T, bool>) and are implemented in completely different libraries / namespaces. This must be the root of the problem, but I don't have a compiler handy to investigate. When in doubt and using LINQ, hover over the function to see which signature it is trying to use and then find examples to match that (for instance look to an OLDER, .NET 2.0 example for using Find before LINQ instead of a newer 3.5 or 4.0 example).

I'm also not sure if the problem will be in some assumption the Predicate version makes about your class "EngineObject" or if it will be a simple issue with the syntax having to be slightly different. Good Luck.

Thanks for the advice - I had a look at the Predicate that the Find operation, and sure enough it's


Predicate<EngineObject> match


I'll keep looking
Oops, sorry.. didn't know you had to have premium membership to do that :)

Anyway... Here's a random wild guess: what happens if you write it like this:
[source lang="csharp"]Predicate<EngineObject> pred = i => i.ID == objectId;

EngineObject obj = objectList.Find( pred );[/source]
Is the errors still with the Find() function, or is it with the predicate?


This surely is weird.. My last advice is to create a new project, isolate your ObjectManager and EngineObject, copy those to the new project and try compiling. If it works, add stuff until it stops working. If it still doesn't work it should be small enough to post the code in code tags here.

This surely is weird.. My last advice is to create a new project, isolate your ObjectManager and EngineObject, copy those to the new project and try compiling. If it works, add stuff until it stops working. If it still doesn't work it should be small enough to post the code in code tags here.


Just tried this out :


Predicate<EngineObject> pred = i => i.ID == objectId;
objectList.Find( pred );


aaaand the same error code... this is getting ridiculous :)
Why don't you rar it and use say http://www.speedyshare.com/ to host it so we can check it out?

Why don't you rar it and use say http://www.speedyshare.com/ to host it so we can check it out?


Done http://www.2shared.com/file/GWlPZyxm/Engine.html
Could you link me the other stuff you have reference on the project? Like JigLibX

#Woops, nevermind, downloading already. Gonna take a look at it right now.
Weird, I just tried


/// <summary>
/// Returns an Object of the supplied type, given it's id
/// </summary>
public T GetObject<T>(int objectId)
{
if (m_objectInstances.ContainsKey(typeof(T)))
{
List<EngineObject> objectList = m_objectInstances[typeof(T)];
objectList.Find(delegate(EngineObject obj) { return obj.ID == objectId; });
}
return default(T);
}


And it compiled perfectly. You just gotta change the signature a bit, since you are receiving a generic T, any type at all, and you actually need a T that is an EngineObject, unless I'm not understanding anything. So it would be:


public T GetObject<T>(int objectId) where T: EngineObject
{
if (m_objectInstances.ContainsKey(typeof(T)))
{
List<EngineObject> objectList = m_objectInstances[typeof(T)];
return (T) objectList.Find(delegate(EngineObject obj) { return obj.ID == objectId; });
}
return default(T);
}


Or


public T GetObject<T>(int objectId) where T: EngineObject
{
if (m_objectInstances.ContainsKey(typeof(T)))
{
List<EngineObject> objectList = m_objectInstances[typeof(T)];
return (T) objectList.Find(obj => obj.ID == objectId);
}
return default(T);
}

This topic is closed to new replies.

Advertisement