C# List<T>.Find

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

Does it work if you extract the lambda you're passing into Find() into a separate function? The error message makes it seem like it's complaining that you're passing it a List<EngineObject> instead of a Predicate<EngineObject>.

Tried adding a method to my class to use for searching, but I get the exact same error back
Advertisement

Seems to me like that should compile. Try using the LINQ extension First instead (just for kicks). Also, do you have some variable named i in scope? Neither should give you the error you are getting though... I can't think of anything that could make the lambda infer as a List..

I looked up how to use LINQ, and the following does work :

/// <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)];
var result = from obj in objectList where obj.ID == objectId select obj;
/*
for( int i = 0; i < objectList.Count; i++ )
{
if( objectList.ID == objectId )
{
return (T)((object)objectList);
}
}
*/
}
return default(T);
}


There are obviously a couple of alternate approaches I can use now, but this Find problem has become something of an academic question smile.png

I looked up how to use LINQ, and the following does work :


That method will always return default(T).

But as an aside, if you're going to look up an object by its id, why not use a dictionary for the collection of EngineObjects as well?


public T GetObject<T>(int objectId) where T : EngineObject
{
Dictionary<int, EngineObject> objects;
if (m_objectInstances.TryGetValue(typeof(T), out objects))
return (T)objects[objectId];
else
return default(T);
}
private Dictionary<Type, Dictionary<int, EngineObject>> m_objectInstances;

current project: Roa

objectList.Find( delegate(EngineObject obj) { return obj.ID == objectId; } );

This also does not work?


[quote name='Capoeirista' timestamp='1347913255' post='4981007']
I looked up how to use LINQ, and the following does work :

That method will always return default(T).
But as an aside, if you're going to look up an object by its id, why not use a dictionary for the collection of EngineObjects as well?

public T GetObject<T>(int objectId) where T : EngineObject
{
Dictionary<int, EngineObject> objects;
if (m_objectInstances.TryGetValue(typeof(T), out objects))
return (T)objects[objectId];
else
return default(T);
}
private Dictionary<Type, Dictionary<int, EngineObject>> m_objectInstances;

[/quote]
I think he knows that will only return Default(T), as he commented the section that was actually going to do something to test the part of the code where he's having issues.

objectList.Find( delegate(EngineObject obj) { return obj.ID == objectId; } );

This also does not work?

No that doesn't work - I get the same compile error as :


objectList.Find( i => i.ID == objectId );

That method will always return default(T).

But as an aside, if you're going to look up an object by its id, why not use a dictionary for the collection of EngineObjects as well?

Hah hah, yeah - I was just trying to test out the compiling... that one won't make it through to a commit :)

I could use a dictionary for the object ids as well, but to start with I'd like to figure out why the Find operation is being so problematic.

Cheers!
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'm glad you found a working solution. If you want to use the Linq extension methods on collections you need to have the "using System.Linq;" line. It got me a bunch of times because it doesn't give you very useful compile errors. Personally I'm a fan of FirstOrDefault<T>, it allows a predicate and also works for empty collections.
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 topic is closed to new replies.

Advertisement