Hi all,
I have created one arraylist which contains no. of objects of a particular class. At the runtime i want to check whether a particular object is exists in the arraylist or not. I tried Contains method of arraylist. But it returns false.
Can i check only the particular field existing in an object from an arraylist??
I m struggling for a solution for the past 2 days.. bt i didnt get the solution.
e.g.
// this property returns a arraylist which contains objects of 'Servicedetails'
ulist = service.ServiceDetails;
I am using a gridview which contains a set of service details.
based on the selected item in the grid create a temporary object and assinging the values to the object and i am checking whether it is existing in the arraylist or not.
I tried the coding as
ulist.Contains(serviceDetail); // but it always returns false.
In the debug mode, i check the ulist , it contains the collection of object with the same property values of the 'serviceDetail' object. but it evaluates to false. Why? Is my method of checking is not correct??
If so what way i can check??
Please help me.... i m waiting for ur solution..
Thankfully,
cssjm
-
-
Because the object in the ArrayList "IS NOT" the same object of ServiceDetails in your "service" object. Although they contain the same set of value, they contains different instance(or you may think "address") value.
You probably need to implement your memberwise comparison method yourself. -
The Contains function will iterate through each item in the collection and call the Equals function against each item, returning the result.
Equals is a function derived from the base class Object and by default it will compare the in-memory address of two items.
Because you create a temporary object, these values will never be the same because you create a brand new object that is not in the ArrayList.
I'd think you could get the original object from the GridView and use that for the compare, but another way is to override the Equals function of your Servicedetails object and create some custom compare functionality. -
cssavinashi wrote:I have created one arraylist which contains no. of objects of a particular class. At the runtime i want to check whether a particular object is exists in the arraylist or not. I tried Contains method of arraylist. But it returns false.
Remember that for reference types in .NET, meaning most non-primitive types, two instances of an object can have the same content and describe the same logical entity, but still be completely different objects:
Person me = new Person("Yggdrasil");
Person meToo = new Person("Yggdrasil");
ArrayList list = new ArrayList();
list.Add(me);
if (list.Contains(meToo)
{
// This will not be called!
}
These two objects are different instances, and thus not equal. You can't find one in an ArrayList using the other.
So what can you do?
1) Override the == operator and Equals method on the given type, so when the ArrayList.Contains() method checks for equality with the contents, it will see both instances as equal.
2) Implement your own Contains() method which iterates over the entire arraylist and checks whether the given property is equal for the objects.
In C# 2.0 I would use a List<MyType> instead of an untyped ArrayList, and use the myList.Exists() method to specify a method that compares the properties:
Person me = new Person("Yggdrasil");
Person meToo = new Person("Yggdrasil");
List<Person> list = new List<Person>();
list.Add(me);
bool exists = list.Exists(new delegate(Person p)
{ return p.Name == meToo.Name; });
-
Hi friends,
Thanks a lot for ur replies...
I tried the method of loop thorough the entire arraylist and take each item from array and cast it as 'sampleDetail' object and i set a boolean variable 'exists = true' (Initially it was false)
And at last i compare the flag variable. If it is true i just update the object. And if it is false then i added it as a new object in to my database.
ulist = service.serviceDetail;
exist = false;
for (int i=0;i<ulist.count;i++)
{
TIAoServiceDetail detail = (TIAoServiceDetail)ulist[i];
if (detail.UID == <tempobject>.UID)
{
exists = true;
}
}
if (exists == true)
{
// update the object
}
else if (exist == false)
{
// add as new object
}
this is what i did finally.. Is it ok?? (b'caz i loop through the entire list for checking. Is it good practice??
Or else what other way around??? Can any1 sugguest me??
Thankfully,
cssjm
-
If the TIAoServiceDetail is a class you have the source code for, then override the Equals method in the TIAoServiceDetail class:
public override bool Equals (object other)
{
bool ret = false;
TIAoServiceDetail otherService = other as TIAoServiceDetail;
if(otherService != null)
{
ret = this.UID == otherService.UID;
}
return ret;
}
THis will mean that the ArrayList.Contains method will work properly as well as many other built-in comparison methods in the .NET framework.
If you don't have the source code for the service detail class, then your method should work, but you'll have to repeat it whenever you do comparisons, so a utility class with a static comparison method might help:
public class ServiceDetailCompare
{
public static bool Compare(TIAoServiceDetail one, TIAoServiceDetail two)
{
return one.UID == two.UID;
}
}
This will take the sting out if you find there are other places where comparisons arise.
Herbie -
Dr Herbie wrote:
public override bool Equals (object other)
{
bool ret = false;
TIAoServiceDetail otherService = other as TIAoServiceDetail;
if(otherService != null)
{
ret = this.UID == otherService.UID;
}
return ret;
}
Wow!
I would that piece of code always write as this:
public override bool Equals(object other)
{
TIAoServiceDetail otherService = other as TIAoServiceDetail;
if (otherService == null)
return false;
return (this.UID == otherService.UID);
}
That's a lot clearer to me then the other one
-
littleguru wrote:

Dr Herbie wrote:
public override bool Equals (object other)
{
bool ret = false;
TIAoServiceDetail otherService = other as TIAoServiceDetail;
if(otherService != null)
{
ret = this.UID == otherService.UID;
}
return ret;
}
Wow!
I would that piece of code always write as this:
public override bool Equals(object other)
{
TIAoServiceDetail otherService = other as TIAoServiceDetail;
if (otherService == null)
return false;
return (this.UID == otherService.UID);
}
That's a lot clearer to me then the other one
I used to work somewhere that insisted that each method only had one exit point, hence my current habits. It's still useful if you use the refactoring tools to pull code sections out into new methods, otherwise if there's a return statement in the code your pulling out, things may not go smoothly.
Herbie
-
littleguru wrote:
public override bool Equals(object other)
{
TIAoServiceDetail otherService = other as TIAoServiceDetail;
if (otherService == null)
return false;
return (this.UID == otherService.UID);
}
Or to go all out:
public override bool Equals(object other)
{
return ((other != null) ? this.UID == ((TIAoServiceDetail)other).UID : false);
}
Gotta love the compactness of C#. I have to work with VB at my current work... which takes HUGE statements... really miss C#
-
prec wrote:
Or to go all out:
public override bool Equals(object other)
{
return ((other != null) ? this.UID == ((TIAoServiceDetail)other).UID : false);
}
Gotta love the compactness of C#. I have to work with VB at my current work... which takes HUGE statements... really miss C#
What happens with:
myServiceDetail.Equals(new SomeRandomObject());
Your nice compact code will crash and burn.
Herbie
-
Dr Herbie wrote:

prec wrote:
Or to go all out:
public override bool Equals(object other)
{
return ((other != null) ? this.UID == ((TIAoServiceDetail)other).UID : false);
}
Gotta love the compactness of C#. I have to work with VB at my current work... which takes HUGE statements... really miss C#
What happens with:
myServiceDetail.Equals(new SomeRandomObject());
Your nice compact code will crash and burn.
Herbie
public override bool Equals(object other)
{
return ((other != null && typeof(other) is TIAoServiceDetail) ? this.UID == ((TIAoServiceDetail)other).UID : false);
}
-
prec wrote:

Dr Herbie wrote: 
prec wrote:
Or to go all out:
public override bool Equals(object other)
{
return ((other != null) ? this.UID == ((TIAoServiceDetail)other).UID : false);
}
Gotta love the compactness of C#. I have to work with VB at my current work... which takes HUGE statements... really miss C#
What happens with:
myServiceDetail.Equals(new SomeRandomObject());
Your nice compact code will crash and burn.
Herbie
public override bool Equals(object other)
{
return ((other != null && typeof(other) is TIAoServiceDetail) ? this.UID == ((TIAoServiceDetail)other).UID : false);
}

Doesn't work too. typeof(XXX) returns a Type object... "is" doesn't work properly then... Btw. doing unecessary casts makes everything slow that is why the "as" statement is introduced... Especially if this should be high performance code. -
littleguru wrote:

prec wrote:
public override bool Equals(object other)
{
return ((other != null && typeof(other) is TIAoServiceDetail) ? this.UID == ((TIAoServiceDetail)other).UID : false);
}

Doesn't work too. typeof(XXX) returns a Type object... "is" doesn't work properly then... Btw. doing unecessary casts makes everything slow that is why the "as" statement is introduced... Especially if this should be high performance code.
Smells of a VB coder to me, there it would be "TypeOf other Is TIAoServiceDetail".
In C# you need to do "other.GetType() == typeof(TIAoServiceDetail)". But littleguru is right; using "as" (TryCast in VB) is faster since it avoids the extra cast.You could condense littleguru's original version into two lines though if you really must:
public override bool Equals(object other)
{
TIAoServiceDetail otherService = other as TIAoServiceDetail;
return otherService != null && otherService.UID == this.UID;
}
And personally I like to do something like this:
class TIAoServiceDetail : IEquatable<TIAoServiceDetail>
{
/* ... */
public override bool Equals(object obj)
{
return Equals(obj as TIAoServiceDetail);
}
#region IEquatable<TIAoServiceDetail> Members
public bool Equals(TIAoServiceDetail other)
{
return other != null && other.UID == this.UID;
}
#endregion
} -
Sven Groot wrote:
You could condense littleguru's original version into two lines though if you really must:
public override bool Equals(object other)
{
TIAoServiceDetail otherService = other as TIAoServiceDetail;
return otherService != null && otherService.UID == this.UID;
}
And personally I like to do something like this:
class TIAoServiceDetail : IEquatable<TIAoServiceDetail>
{
/* ... */
public override bool Equals(object obj)
{
return Equals(obj as TIAoServiceDetail);
}
#region IEquatable<TIAoServiceDetail> Members
public bool Equals(TIAoServiceDetail other)
{
return other != null && other.UID == this.UID;
}
#endregion
}
Oh dear, falling foul of myTIAoServiceDetail.Equals(new SomeRandomObject()); again! the 'as' operator returns null if the object is not castable, doesn't it?
Looks like I really need to dedicate some time to the .NET 2.0 generics libraries -- I've never seen IEquatable<> before. Unfortunately at work we're maxed out until the spring, so there's no time for training.
Herbie
-
Sven Groot wrote:
Smells of a VB coder to me, there it would be "TypeOf other Is TIAoServiceDetail".
In C# you need to do "other.GetType() == typeof(TIAoServiceDetail)". But littleguru is right; using "as" (TryCast in VB) is faster since it avoids the extra cast.
I'd rather not be called a VB coder
I prefer C# by far... I've just had my hands dirty for too long. I can't write proper C# code out of my head any longer [C]
But let's leave it at that, i believe the original poster got his question answered in depth.
-
Dr Herbie wrote:

Sven Groot wrote:
class TIAoServiceDetail : IEquatable<TIAoServiceDetail>
{
/* ... */
public override bool Equals(object obj)
{
return Equals(obj as TIAoServiceDetail);
}
#region IEquatable<TIAoServiceDetail> Members
public bool Equals(TIAoServiceDetail other)
{
return other != null && other.UID == this.UID;
}
#endregion
}
Oh dear, falling foul of myTIAoServiceDetail.Equals(new SomeRandomObject()); again! the 'as' operator returns null if the object is not castable, doesn't it?
Yes it does, which the other overload catches by checking for null, thus returning false. I fail to see where it "falls foul".
EDIT: If you're thinking it would call the Equals(object) overload again (thus causing a stack overflow) that isn't the case. Overload resolution isn't dynamic; the compiler determines that the type of "obj as TIAoServiceDetail" is TIAoServiceDetail, thus the Equals(TIAoServiceDetail) overload will always be called.
If you weren't thinking that, I apologize for even suggesting it.
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.