Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / February 2008

Tip: Looking for answers? Try searching our database.

Compare 2 objects

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
tshad - 27 Feb 2008 00:18 GMT
I am trying to take part of my functions out of my Sort routine to do a
compare (as it does) where I just find out if object 1 is less then, equal
to or greater than object 2

I have the following:

  ProjectTableName ptn1 = projectTables.Find(delegate(ProjectTableName ptn)
{return ptn.TableName == "employee";});
  ProjectTableName ptn2 = projectTables.Find(delegate(ProjectTableName ptn)
{ return ptn.TableName == "customer"; });

  int temp = delegate(ProjectTableName ptn1, ProjectTableName ptn2) {return
ptn1.ProcessOrder.CompareTo(ptn2);};

I am getting an error on the ptn1 and ptn2 in the last line that says:

A local variable named 'ptn1' cannot be declared in this scope because it
would give a different meaning to 'ptn1', which is already used in a 'parent
or current' scope to denote something else

The same for ptn2.

I am also getting an error:

  Cannot convert anonymous method block to type 'int' because it is not a
delegate type

In the first 2 lines, I am trying to get a ProjectTableName object where the
TableName = "employee" and one that equals "customer".

Then I want to compare the objects using the ProcessOrder Property.

I want to eventually put the 2 Finds inside the last line to give me just
one line, but I was having similar problems so I tried to split it out first
just to get it to work.

How would I change this to make it work?

Thanks,

Tom
Marc Gravell - 27 Feb 2008 00:35 GMT
>    int temp = delegate(ProjectTableName ptn1, ProjectTableName ptn2) {return
> ptn1.ProcessOrder.CompareTo(ptn2);};
> ...
> Then I want to compare the objects using the ProcessOrder Property.

Forgetting the return type, this would define a delegate, not an
integer result - i.e. a Comparer<ProjectTableName>
Well, what is ProcessOrder? if it is IComparable[<T>] perhaps simply:

int tmp = ptn1.ProcessOrder.CompareTo(ptn2.ProcessOrder);

?
tshad - 27 Feb 2008 00:50 GMT
>> int temp = delegate(ProjectTableName ptn1, ProjectTableName ptn2)
>> {return ptn1.ProcessOrder.CompareTo(ptn2);};
[quoted text clipped - 6 lines]
>
> int tmp = ptn1.ProcessOrder.CompareTo(ptn2.ProcessOrder);

That was what I came up with also.  And it works great.

But how do I do it in one statement?  I assume I would use delegates that
would pass back the ProjectTableName.

  ProjectTableName ptn1 = projectTables.Find(delegate(ProjectTableName ptn)
{return ptn.TableName == "employee";});
  ProjectTableName ptn2 = projectTables.Find(delegate(ProjectTableName ptn)
{ return ptn.TableName == "customer"; });

int tmp = ptn1.ProcessOrder.CompareTo(ptn2.ProcessOrder);

Another wrinkle would be to make sure they are not null.  Can I do that with
delegates?

Thanks,

Tom
Marc Gravell - 27 Feb 2008 07:02 GMT
> But how do I do it in one statement?
Why do you need to? How would that help?

> I assume I would use delegates that would pass back the ProjectTableName.
Find already does that...

> Another wrinkle would be to make sure they are not null.
Is "ProcessOrder" the natural sequence? If so, you could make
ProjectTableName : IComparable<ProjectTableName>, and use
Comparer<ProjectTableName>.Deafult.Compare, which handles null...
otherwise just code it!

Unless you have an overriding necessity, you can get the single-
statement by simply refactoring the body into a helper method:

       static void Main()
       {
           List<ProjectTableName> projectTables = new
List<ProjectTableName>();
           int result = CompareByName(projectTables, "employee",
"customer");
       }
       public static int CompareByName(
               List<ProjectTableName> tables,
               string tableName1, string tableName2) {
           var ptn1 = tables.Find(ptn => ptn.TableName ==
tableName1);
           var ptn2 = tables.Find(ptn => ptn.TableName ==
tableName2);
           // handle nulls (not found)
           if(ReferenceEquals(ptn1,ptn2)) return 0;
           if(ReferenceEquals(ptn1,null)) return -1;
           if(ReferenceEquals(ptn2,null)) return 1;
           return ptn1.ProcessOrder.CompareTo(ptn2.ProcessOrder);
       }
tshad - 27 Feb 2008 18:39 GMT
>> But how do I do it in one statement?
> Why do you need to? How would that help?
>
>> I assume I would use delegates that would pass back the ProjectTableName.
> Find already does that...

Are you saying that I should be doing it differently than:

  ProjectTableName ptn1 = projectTables.Find(delegate(ProjectTableName ptn)
{return ptn.TableName == "employee";});

>> Another wrinkle would be to make sure they are not null.
> Is "ProcessOrder" the natural sequence? If so, you could make
> ProjectTableName : IComparable<ProjectTableName>, and use
> Comparer<ProjectTableName>.Deafult.Compare, which handles null...
> otherwise just code it!

ProcessOrder is just the order that a table has to inserted.  I need to
track whether a key I am using is a foreign key to a parent table or to a
lookup table.  If when I compare the ProcessOrder to the ProcessOrder of the
current table and I get a -1, am dealing with a Parent table, if a 1 then I
am dealing with a lookup table.

So what I am doing is getting the ProjectTableName object for the current
table name and one for the one I want to compare then compare the
ProcessOrder properties of each.

Doing it as I did works fine and handles the null possibility as I can do a
null test on both objects before actually doing the compare.

I was just looking to see how I would do it in one statement (if that was
even feasible).  Not that I necessarily would but wanted to see what it
would entail and then decide which was the better way.

> Unless you have an overriding necessity, you can get the single-
> statement by simply refactoring the body into a helper method:
[quoted text clipped - 19 lines]
>            return ptn1.ProcessOrder.CompareTo(ptn2.ProcessOrder);
>        }

That was what I was looking for.  Just another way to do it.

If it was you, which would you do?   The 2 statements to get the object,
test for null, then compare the objects.  Or using your other method.

By the way, what is the "=>" for.

Thanks,

Tom
Marc Gravell - 28 Feb 2008 05:24 GMT
> If it was you, which would you do?   The 2 statements to get the object,
> test for null, then compare the objects.  Or using your other method.

Sorry, I'm confused; which 2 approaches are we comparing?

> By the way, what is the "=>" for.

C# 3 lambda syntax:
Find(ptn => ptn.TableName == tableName2)
is the same as
Find(delegate (ProjectTableName ptn) {return ptn.TableName ==
tableName2;});

Note in particular that nothing we have removed is actually necessary
to understand the meaning; easier to understand without wading through
fluff

Marc
tshad - 28 Feb 2008 21:15 GMT
>> If it was you, which would you do? The 2 statements to get the
>> object, test for null, then compare the objects. Or using your other
>> method.
>
> Sorry, I'm confused; which 2 approaches are we comparing?

The first method where you get the 2 ProjectTableName objects then compare
them
*****************************************************
int tmp;
 ProjectTableName ptn1 = projectTables.Find(delegate(ProjectTableName ptn)
{return ptn.TableName == "employee";});
  ProjectTableName ptn2 = projectTables.Find(delegate(ProjectTableName ptn)
{ return ptn.TableName == "customer"; });

if (ptn1 != null && pnt2 != null)
 tmp  = ptn1.ProcessOrder.CompareTo(ptn2.ProcessOrder);
else
   do something
*********************************************************

VS

Your other method of using a helper method:
***********************************************************
       static void Main()
       {
           List<ProjectTableName> projectTables = new
List<ProjectTableName>();
           int result = CompareByName(projectTables, "employee",
"customer");
       }
       public static int CompareByName(
               List<ProjectTableName> tables,
               string tableName1, string tableName2) {
           var ptn1 = tables.Find(ptn => ptn.TableName ==
tableName1);
           var ptn2 = tables.Find(ptn => ptn.TableName ==
tableName2);
           // handle nulls (not found)
           if(ReferenceEquals(ptn1,ptn2)) return 0;
           if(ReferenceEquals(ptn1,null)) return -1;
           if(ReferenceEquals(ptn2,null)) return 1;
           return ptn1.ProcessOrder.CompareTo(ptn2.ProcessOrder);
       }
****************************************************

Thanks,

Tom

>> By the way, what is the "=>" for.
>
[quoted text clipped - 9 lines]
>
> Marc
Marc Gravell - 29 Feb 2008 08:07 GMT
It depends entirely on how much I need to re-use ;-p

If the "find 2 rows [if they exist] by <x>, and compare by <y>" is quite
common, then perhaps (where "tables" is a List<ProjectTableName>):

int value = tables.Compare(ptn => ptn.TableName,
           "Foo", "Bar", ptn => ptn.ProcessOrder);

using the extension method below [untested]... this locates the 2 rows with
TableName "Foo" and "Bar" respectively, and if they both exist uses the
standard comparison based on their ProcessOrder. If either or both is
missing, standard null rules apply.

Marc

static int Compare<TSource, TFindValue, TCompareValue>(this List<TSource>
source,
       Func<TSource, TFindValue> findSelector, TFindValue x, TFindValue y,
       Func<TSource, TCompareValue> compareSelector) where TSource : class
   {
       EqualityComparer<TFindValue> findComparer =
EqualityComparer<TFindValue>.Default;
       TSource xItem = source.Find(item =>
findComparer.Equals(findSelector(item), x)),
           yItem = source.Find(item =>
findComparer.Equals(findSelector(item), y));
       if (ReferenceEquals(x, y)) return 0;
       if (ReferenceEquals(x, null)) return -1;
       if (ReferenceEquals(y, null)) return 1;
       return
Comparer<TCompareValue>.Default.Compare(compareSelector(xItem),
compareSelector(yItem));
   }

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.