By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,673 Members | 1,268 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,673 IT Pros & Developers. It's quick & easy.

Inheritance sort question

P: n/a
I have a class that needs to have several different kinds of sorting
routines on an ArrayList that it needs to conditionally do based upon the
data. I have successfully created a class that implements IComparer and
does the sort correctly for one of these sort types. This class's
definition is like:

// Sort class that implements IComparer so
public class CompareFields1 : IComparer
{
public int Compare(object a, object b)
{
// Code that appears in every sort's Compare routine
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (a.GetType() != b.GetType())
{
throw new ArgumentException();
}

// Now that the inputs are valid, do the actual compare
/*... ...actual compare code here... ...*/
}
}
Now I want to make another sort algorithm (CompareFields2). This definition
will be have the same layout as the above one, but the actual compare code
is going to be different. I would like to try and factor out the common
code, but I can't seem to think of a good class design for it since this
isn't in the constructor. I thought of factoring the code into a utility
class, but that requires me to call the utility class and get the response
back, which is still about 5 lines of code I would need to duplicate. Any
ideas on what I should be doing?

Thanks!
Nov 13 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
DancnDude,

I would take the CompareFields1 class and rename it CompareFieldsBase.
In the Compare method, I would have the common code, and then I would have
the specific compare code call out to a virtual method. Then, have classes
that derive from CompareFieldsBase which would override the virtual method.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- ni**************@exisconsulting.com

"DancnDude" <da*******@hotmail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I have a class that needs to have several different kinds of sorting
routines on an ArrayList that it needs to conditionally do based upon the
data. I have successfully created a class that implements IComparer and
does the sort correctly for one of these sort types. This class's
definition is like:

// Sort class that implements IComparer so
public class CompareFields1 : IComparer
{
public int Compare(object a, object b)
{
// Code that appears in every sort's Compare routine
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (a.GetType() != b.GetType())
{
throw new ArgumentException();
}

// Now that the inputs are valid, do the actual compare
/*... ...actual compare code here... ...*/
}
}
Now I want to make another sort algorithm (CompareFields2). This definition will be have the same layout as the above one, but the actual compare code
is going to be different. I would like to try and factor out the common
code, but I can't seem to think of a good class design for it since this
isn't in the constructor. I thought of factoring the code into a utility
class, but that requires me to call the utility class and get the response
back, which is still about 5 lines of code I would need to duplicate. Any
ideas on what I should be doing?

Thanks!

Nov 13 '05 #2

P: n/a
Thanks! That is exactly what I want it to do, but just couldn't think of
the right way to do it. :)

"Nicholas Paldino [.NET/C# MVP]" <ni**************@exisconsulting.com> wrote
in message news:Od**************@TK2MSFTNGP10.phx.gbl...
DancnDude,

I would take the CompareFields1 class and rename it CompareFieldsBase.
In the Compare method, I would have the common code, and then I would have
the specific compare code call out to a virtual method. Then, have classes that derive from CompareFieldsBase which would override the virtual method.
Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- ni**************@exisconsulting.com

"DancnDude" <da*******@hotmail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I have a class that needs to have several different kinds of sorting
routines on an ArrayList that it needs to conditionally do based upon the data. I have successfully created a class that implements IComparer and
does the sort correctly for one of these sort types. This class's
definition is like:

// Sort class that implements IComparer so
public class CompareFields1 : IComparer
{
public int Compare(object a, object b)
{
// Code that appears in every sort's Compare routine
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (a.GetType() != b.GetType())
{
throw new ArgumentException();
}

// Now that the inputs are valid, do the actual compare
/*... ...actual compare code here... ...*/
}
}
Now I want to make another sort algorithm (CompareFields2). This

definition
will be have the same layout as the above one, but the actual compare code is going to be different. I would like to try and factor out the common
code, but I can't seem to think of a good class design for it since this
isn't in the constructor. I thought of factoring the code into a utility class, but that requires me to call the utility class and get the response back, which is still about 5 lines of code I would need to duplicate. Any ideas on what I should be doing?

Thanks!


Nov 13 '05 #3

P: n/a
No, it's not derived from CompareFields1. They would all be derived from
CompareBase as Nicholas suggested. The part that I couldn't think to do was
having the base's Compare method call a virtual method whose implementation
will only really exist in the derived classes. The virtual method kinda
threw me since I never had a need to use one until now.

Thanks for the suggestion!

"Jay B. Harlow [MVP - Outlook]" <Ja********@email.msn.com> wrote in message
news:#I**************@TK2MSFTNGP12.phx.gbl...
DancnDude,
Is CompareFields2 derived from CompareFields1?

If it is, use the Template Method Pattern for the "actual compare code
here". I would then consider making a new abstract base class that both
CompareFields1 & CompareFields2 inherit from, but you can keep
CompareFields1 as the base.
public class CompareFields1 : IComparer
{
public int Compare(object a, object b)
{
// Code that appears in every sort's Compare routine
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (a.GetType() != b.GetType())
{
throw new ArgumentException();
}

// Now that the inputs are valid, do the actual compare
return OnCompare(a, b)
}


protected virtual int OnCompare(object a, object b)
{
/*... ...actual compare code here... ...*/
}
}


public class CompareField2 : CompareFields1
{
protected overrides int OnCompare(object a, object b)
{
/*... ...actual compare code here... ...*/
}
}

I've been reading "Test-Driven Development - By Example" by Kent Beck,

from Addison Wesley. He mentions a Pluggable Selector pattern, that may be useful here. Using a Delegate in .NET would simplify the Pluggable Selector
pattern. With the Pluggable Selector you only have one class, this class
would have a method for each sorting routine. I would use a Delegate to hold that sorting routine.

public class MyComparer : IComparer
{

delegate int CompareRoutine(object a, object b);

readonly CompareRoutine OnCompare;

public MyComparer()
{
OnCompare = new CompareRoutine(CompareFields1);
}

public int Compare(object a, object b)
{
// Code that appears in every sort's Compare routine ...
// Now that the inputs are valid, do the actual compare

return OnCompare(a, b)
}

private virtual int CompareFields1(object a, object b)
{
/*... ...actual compare code here... ...*/

}

private virtual int CompareFields2(object a, object b)
{
/*... ...actual compare code here... ...*/

}

}

The problem now becomes how to initialize OnCompare, I would consider

either a Factory Method or enum passed to the constructor to decide which compare
routine I was going to use. (The Factory method would send the delegate
itself to the constructor, I would have a static method for each sort
method...

Hope this helps
Jay

"DancnDude" <da*******@hotmail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I have a class that needs to have several different kinds of sorting
routines on an ArrayList that it needs to conditionally do based upon the data. I have successfully created a class that implements IComparer and
does the sort correctly for one of these sort types. This class's
definition is like:

// Sort class that implements IComparer so
public class CompareFields1 : IComparer
{
public int Compare(object a, object b)
{
// Code that appears in every sort's Compare routine
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (a.GetType() != b.GetType())
{
throw new ArgumentException();
}

// Now that the inputs are valid, do the actual compare
/*... ...actual compare code here... ...*/
}
}
Now I want to make another sort algorithm (CompareFields2). This

definition
will be have the same layout as the above one, but the actual compare code is going to be different. I would like to try and factor out the common
code, but I can't seem to think of a good class design for it since this
isn't in the constructor. I thought of factoring the code into a utility class, but that requires me to call the utility class and get the response back, which is still about 5 lines of code I would need to duplicate. Any ideas on what I should be doing?

Thanks!


Nov 13 '05 #4

P: n/a
That's exactly what I did and it's working wonderfully. :)

"Nicholas Paldino [.NET/C# MVP]" <ni**************@exisconsulting.com> wrote
in message news:OK**************@TK2MSFTNGP11.phx.gbl...
DancnDude,

Better yet, for a cleaner implementation, make the CompareFieldsBase
class abstract and make the virtual method abstract as well. This way, your base class could not be instantiated, and you would force the override of
the method in derived classes (if you wanted this behavior, that is).
--
- Nicholas Paldino [.NET/C# MVP]
- ni**************@exisconsulting.com

"DancnDude" <da*******@hotmail.com> wrote in message
news:OI**************@TK2MSFTNGP12.phx.gbl...
No, it's not derived from CompareFields1. They would all be derived from
CompareBase as Nicholas suggested. The part that I couldn't think to do

was
having the base's Compare method call a virtual method whose

implementation
will only really exist in the derived classes. The virtual method kinda
threw me since I never had a need to use one until now.

Thanks for the suggestion!

"Jay B. Harlow [MVP - Outlook]" <Ja********@email.msn.com> wrote in

message
news:#I**************@TK2MSFTNGP12.phx.gbl...
DancnDude,
Is CompareFields2 derived from CompareFields1?

If it is, use the Template Method Pattern for the "actual compare code
here". I would then consider making a new abstract base class that both CompareFields1 & CompareFields2 inherit from, but you can keep
CompareFields1 as the base.

> public class CompareFields1 : IComparer
> {
> public int Compare(object a, object b)
> {
> // Code that appears in every sort's Compare routine
> if (a == b) return 0;
> if (a == null) return -1;
> if (b == null) return 1;
> if (a.GetType() != b.GetType())
> {
> throw new ArgumentException();
> }
>
> // Now that the inputs are valid, do the actual compare

return OnCompare(a, b)

> }

protected virtual int OnCompare(object a, object b)
{
/*... ...actual compare code here... ...*/
}
> }

public class CompareField2 : CompareFields1
{
protected overrides int OnCompare(object a, object b)
{
/*... ...actual compare code here... ...*/
}
}

I've been reading "Test-Driven Development - By Example" by Kent Beck,

from
Addison Wesley. He mentions a Pluggable Selector pattern, that may be

useful
here. Using a Delegate in .NET would simplify the Pluggable Selector
pattern. With the Pluggable Selector you only have one class, this class would have a method for each sorting routine. I would use a Delegate to
hold
that sorting routine.

public class MyComparer : IComparer
{

delegate int CompareRoutine(object a, object b);

readonly CompareRoutine OnCompare;

public MyComparer()
{
OnCompare = new CompareRoutine(CompareFields1);
}

public int Compare(object a, object b)
{
> // Code that appears in every sort's Compare routine
...
> // Now that the inputs are valid, do the actual compare
return OnCompare(a, b)
}

private virtual int CompareFields1(object a, object b)
{
> /*... ...actual compare code here... ...*/
}

private virtual int CompareFields2(object a, object b)
{
> /*... ...actual compare code here... ...*/
}

}

The problem now becomes how to initialize OnCompare, I would consider

either
a Factory Method or enum passed to the constructor to decide which compare routine I was going to use. (The Factory method would send the
delegate itself to the constructor, I would have a static method for each sort
method...

Hope this helps
Jay

"DancnDude" <da*******@hotmail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
> I have a class that needs to have several different kinds of sorting
> routines on an ArrayList that it needs to conditionally do based

upon the
> data. I have successfully created a class that implements IComparer and > does the sort correctly for one of these sort types. This class's
> definition is like:
>
> // Sort class that implements IComparer so
> public class CompareFields1 : IComparer
> {
> public int Compare(object a, object b)
> {
> // Code that appears in every sort's Compare routine
> if (a == b) return 0;
> if (a == null) return -1;
> if (b == null) return 1;
> if (a.GetType() != b.GetType())
> {
> throw new ArgumentException();
> }
>
> // Now that the inputs are valid, do the actual compare
> /*... ...actual compare code here... ...*/
> }
> }
>
>
> Now I want to make another sort algorithm (CompareFields2). This
definition
> will be have the same layout as the above one, but the actual
compare code
> is going to be different. I would like to try and factor out the common > code, but I can't seem to think of a good class design for it since this > isn't in the constructor. I thought of factoring the code into a

utility
> class, but that requires me to call the utility class and get the

response
> back, which is still about 5 lines of code I would need to

duplicate. Any
> ideas on what I should be doing?
>
> Thanks!
>
>



Nov 13 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.