Code Reuse.... What level should I expect?

R

RichB

I am just trying to get to grips with C# and OOP, and one of the benefits
would seem to be code reuse. However I am not sure where to draw the line. I
have the following section of code:

if (ev.locationList != null)
{
//isListNull = true ensures that we do not recheck the list
every time we add a new item
bool isListNull = false;

if (this.locationList == null)
{
this.locationList = new List<EventLocation>();
isListNull = true;
}
foreach (LocationInfoDTO loList in ev.locationList)
{
EventLocation loc = null;
if (!isListNull)
{
//listMatch is used by the Find Predicate to
match to objects already within the LocationList
listMatch = loList;
loc =
this.locationList.Find(EventLocationListMatch);
}
if (loc == null)
{
this.LocationList.Add(EventLocation.Create(loList));
}
else
{
loc.Update(loList);
}
}
}

Which is used in my constructor to take the inputs in the form of a DTO (ev)
and translates them into an list object within a business object. I find
that in another class I have a need to populate another list of a different
type from a different type of DTO. Apart from these being different types
the method of populating the list in the other class is identical and
therefore I would live to reuse the code, rather than cutting and pasting. I
therefore have 2 questions:

1. Are my expectations correct, should I be able to create a generic helper
method that does the tasks needed? i.e. :
a.. if the list does not already exist then create it.
b. iterate through each list item in the dto.
c. if the list already existed, then check if the item being added already
exists and update rather than create it
d. else add a new item to the list.

2. If I should be able to produce a generic method, then where should I be
looking for inspiration?

Thanks, Richard
 
A

Arved Sandstrom

RichB said:
I am just trying to get to grips with C# and OOP, and one of the benefits
would seem to be code reuse. However I am not sure where to draw the line.
I have the following section of code:
[ SNIP ]
Which is used in my constructor to take the inputs in the form of a DTO
(ev) and translates them into an list object within a business object. I
find that in another class I have a need to populate another list of a
different type from a different type of DTO. Apart from these being
different types the method of populating the list in the other class is
identical and therefore I would live to reuse the code, rather than
cutting and pasting. I therefore have 2 questions:

1. Are my expectations correct, should I be able to create a generic
helper method that does the tasks needed? i.e. :
a.. if the list does not already exist then create it.
b. iterate through each list item in the dto.
c. if the list already existed, then check if the item being added already
exists and update rather than create it
d. else add a new item to the list.

2. If I should be able to produce a generic method, then where should I be
looking for inspiration?

Thanks, Richard

You're fundamentally looking at set operations here, however you may choose
to implement that. Each item has a property or properties that distinguishes
it from any other. As I understand it, the C# options available to you for
actual implementation include HashSet, Hashtable and Dictionary (the latter
two have the same functionality). For coding uniqueness for your DTOs see
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

AHS
 
R

RichB

Thanks Peter, that is a really good start in two ways... firstly gives me
the confidence to spend some time working it out, without feeling it may all
be for nought, and secondly the tips on improving the use of the find
method. Having said that the match criteria will be different between the
different lists, so I'm not sure that I can use a anonymous method or lambda
expression, but will consider it when I get that far in working out a
common approach.

One last thing, just to clarify the List<LocationInfoDTO> is part of the
EventDTO class structure and provides the raw data to instantiate a Event
class, which has a List<EventLocation>. EventLocation and LocationInfo DTO
map to each other. It is this mapping that I am trying to acheive in this
case.

Thanks for your help, I suspect that I shall be back for a little more, but
in the meantime I have enough to get me started.

Thanks, Richard

[...]
1. Are my expectations correct, should I be able to create a generic
helper method that does the tasks needed? [...]

2. If I should be able to produce a generic method, then where should I
be looking for inspiration?

I don't know how to answer your second question. The answer to your first
question is probably "yes", but we don't really have enough information
about the classes to answer with authority. Looking at the code you
posted, it seems possible that "LocationInfoDTO" is a sub-class of
"EventLocation". If that's correct, then I would expect the code you
posted to be easily moved to a helper method, probably in a base class
shared by any objects that would use it.

By the way, you may also want to read up on anonymous methods and lambda
expressions. You appear to be using a member field to store state for
your predicate passed to Find(), but this can be addressed in a cleaner,
more readable fashion with an anonymous method or lambda expression. For
example, instead of:

listMatch = loList;
loc = this.locationList.Find(EventLocationListMatch);

(and of course, whatever the implementation of "EventLocationListMatch()"
is)

you could have:

loc = this.locationList.Find(lo => lo == loList);

or:

loc = this.locationList.Find(delegate(EventLocation lo) { return lo ==
loList; });

Pete
 
R

RichB

Arved,

Thanks, for your reply. I assume that you are suggesting that I use a
hashcode as a key for my hashtable perform a comparison. That probably
replaces the loc = this.locationList.Find(eventLocationListMatch) with a
much cleaner approach.

thanks,
Richard


Arved Sandstrom said:
RichB said:
I am just trying to get to grips with C# and OOP, and one of the benefits
would seem to be code reuse. However I am not sure where to draw the line.
I have the following section of code:
[ SNIP ]
Which is used in my constructor to take the inputs in the form of a DTO
(ev) and translates them into an list object within a business object. I
find that in another class I have a need to populate another list of a
different type from a different type of DTO. Apart from these being
different types the method of populating the list in the other class is
identical and therefore I would live to reuse the code, rather than
cutting and pasting. I therefore have 2 questions:

1. Are my expectations correct, should I be able to create a generic
helper method that does the tasks needed? i.e. :
a.. if the list does not already exist then create it.
b. iterate through each list item in the dto.
c. if the list already existed, then check if the item being added
already exists and update rather than create it
d. else add a new item to the list.

2. If I should be able to produce a generic method, then where should I
be looking for inspiration?

Thanks, Richard

You're fundamentally looking at set operations here, however you may
choose to implement that. Each item has a property or properties that
distinguishes it from any other. As I understand it, the C# options
available to you for actual implementation include HashSet, Hashtable and
Dictionary (the latter two have the same functionality). For coding
uniqueness for your DTOs see
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

AHS
 
R

RichB

Thanks for your help. In the end it was pretty easy to solve... Just needed
the confidence to spend the time. I also in the end stayed with the List and
Find(Predicate<T>) method and used an anonymous delegate, which removes the
need for the member field as you advised.

Thanks for the help.

Richard


RichB said:
Thanks Peter, that is a really good start in two ways... firstly gives me
the confidence to spend some time working it out, without feeling it may
all be for nought, and secondly the tips on improving the use of the find
method. Having said that the match criteria will be different between the
different lists, so I'm not sure that I can use a anonymous method or
lambda expression, but will consider it when I get that far in working
out a common approach.

One last thing, just to clarify the List<LocationInfoDTO> is part of the
EventDTO class structure and provides the raw data to instantiate a Event
class, which has a List<EventLocation>. EventLocation and LocationInfo DTO
map to each other. It is this mapping that I am trying to acheive in this
case.

Thanks for your help, I suspect that I shall be back for a little more,
but in the meantime I have enough to get me started.

Thanks, Richard

[...]
1. Are my expectations correct, should I be able to create a generic
helper method that does the tasks needed? [...]

2. If I should be able to produce a generic method, then where should I
be looking for inspiration?

I don't know how to answer your second question. The answer to your first
question is probably "yes", but we don't really have enough information
about the classes to answer with authority. Looking at the code you
posted, it seems possible that "LocationInfoDTO" is a sub-class of
"EventLocation". If that's correct, then I would expect the code you
posted to be easily moved to a helper method, probably in a base class
shared by any objects that would use it.

By the way, you may also want to read up on anonymous methods and lambda
expressions. You appear to be using a member field to store state for
your predicate passed to Find(), but this can be addressed in a cleaner,
more readable fashion with an anonymous method or lambda expression. For
example, instead of:

listMatch = loList;
loc = this.locationList.Find(EventLocationListMatch);

(and of course, whatever the implementation of "EventLocationListMatch()"
is)

you could have:

loc = this.locationList.Find(lo => lo == loList);

or:

loc = this.locationList.Find(delegate(EventLocation lo) { return lo ==
loList; });

Pete
 
A

Arne Vajhøj

RichB said:
I am just trying to get to grips with C# and OOP, and one of the
benefits would seem to be code reuse. However I am not sure where to
draw the line. I have the following section of code:

if (ev.locationList != null)
{
//isListNull = true ensures that we do not recheck the
list every time we add a new item
bool isListNull = false;

if (this.locationList == null)
{
this.locationList = new List<EventLocation>();
isListNull = true;
}
foreach (LocationInfoDTO loList in ev.locationList)
{
EventLocation loc = null;
if (!isListNull)
{
//listMatch is used by the Find Predicate to
match to objects already within the LocationList
listMatch = loList;
loc =
this.locationList.Find(EventLocationListMatch);
}
if (loc == null)
{
this.LocationList.Add(EventLocation.Create(loList));
}
else
{
loc.Update(loList);
}
}
}

Which is used in my constructor to take the inputs in the form of a DTO
(ev) and translates them into an list object within a business object. I
find that in another class I have a need to populate another list of a
different type from a different type of DTO. Apart from these being
different types the method of populating the list in the other class is
identical and therefore I would live to reuse the code, rather than
cutting and pasting. I therefore have 2 questions:

1. Are my expectations correct, should I be able to create a generic
helper method that does the tasks needed? i.e. :
a.. if the list does not already exist then create it.
b. iterate through each list item in the dto.
c. if the list already existed, then check if the item being added
already exists and update rather than create it
d. else add a new item to the list.

2. If I should be able to produce a generic method, then where should I
be looking for inspiration?

You can and should reuse code.

I also think the code can be simplified a bit.

For inspiration:

public static List<T2> DTO2BO<T1,T2>(List<T1> list, Predicate<T1> p)
{
return list.FindAll(p).ConvertAll<T2>(new Converter<T1,
T2>(delegate(T1 o) { return (T2)Activator.CreateInstance(typeof(T2), new
object[] { o }); }));
}

I have attached a full example below.

Arne

=========================================================

using System;
using System.Collections.Generic;

namespace E
{
public class DTOEx
{
private int iv;
private String sv;
public DTOEx(int iv, string sv)
{
this.iv = iv;
this.sv = sv;
}
public int Iv
{
get
{
return iv;
}
set
{
iv = value;
}
}
public string Sv
{
get
{
return sv;
}
set
{
sv = value;
}
}
public override string ToString()
{
return "[DTO:" + iv + "," + sv + "]";
}
}
public class BOEx
{
private int iv;
private String sv;
public BOEx(int iv, string sv)
{
this.iv = iv;
this.sv = sv;
}
public BOEx(DTOEx o)
{
this.iv = o.Iv;
this.sv = o.Sv;
}
public int Iv
{
get
{
return iv;
}
set
{
iv = value;
}
}
public string Sv
{
get
{
return sv;
}
set
{
sv = value;
}
}
public override string ToString()
{
return "[BO:" + iv + "," + sv + "]";
}
}
public class Program
{
public static List<T2> DTO2BO<T1,T2>(List<T1> list,
Predicate<T1> p)
{
return list.FindAll(p).ConvertAll<T2>(new Converter<T1,
T2>(delegate(T1 o) { return (T2)Activator.CreateInstance(typeof(T2), new
object[] { o }); }));
}
public static void Main(string[] args)
{
List<DTOEx> dtoexlist = new List<DTOEx>();
dtoexlist.Add(new DTOEx(1, "A"));
dtoexlist.Add(new DTOEx(2, "BB"));
dtoexlist.Add(new DTOEx(3, "CCC"));
foreach(DTOEx o in dtoexlist)
{
Console.WriteLine(o);
}
List<BOEx> boexlist = DTO2BO<DTOEx,BOEx>(dtoexlist,
delegate(DTOEx o) { return o.Iv > 1; });
foreach(BOEx o in boexlist)
{
Console.WriteLine(o);
}
Console.ReadKey();
}
}
}
 
R

RichB

Thanks Arne,

Very neat, but I've actually done it in a more verbose way, using
inheritance and some simplified generics.

Richard
Arne Vajhøj said:
RichB said:
I am just trying to get to grips with C# and OOP, and one of the benefits
would seem to be code reuse. However I am not sure where to draw the
line. I have the following section of code:

if (ev.locationList != null)
{
//isListNull = true ensures that we do not recheck the
list every time we add a new item
bool isListNull = false;

if (this.locationList == null)
{
this.locationList = new List<EventLocation>();
isListNull = true;
}
foreach (LocationInfoDTO loList in ev.locationList)
{
EventLocation loc = null;
if (!isListNull)
{
//listMatch is used by the Find Predicate to
match to objects already within the LocationList
listMatch = loList;
loc =
this.locationList.Find(EventLocationListMatch);
}
if (loc == null)
{

this.LocationList.Add(EventLocation.Create(loList));
}
else
{
loc.Update(loList);
}
}
}

Which is used in my constructor to take the inputs in the form of a DTO
(ev) and translates them into an list object within a business object. I
find that in another class I have a need to populate another list of a
different type from a different type of DTO. Apart from these being
different types the method of populating the list in the other class is
identical and therefore I would live to reuse the code, rather than
cutting and pasting. I therefore have 2 questions:

1. Are my expectations correct, should I be able to create a generic
helper method that does the tasks needed? i.e. :
a.. if the list does not already exist then create it.
b. iterate through each list item in the dto.
c. if the list already existed, then check if the item being added
already exists and update rather than create it
d. else add a new item to the list.

2. If I should be able to produce a generic method, then where should I
be looking for inspiration?

You can and should reuse code.

I also think the code can be simplified a bit.

For inspiration:

public static List<T2> DTO2BO<T1,T2>(List<T1> list, Predicate<T1> p)
{
return list.FindAll(p).ConvertAll<T2>(new Converter<T1,
T2>(delegate(T1 o) { return (T2)Activator.CreateInstance(typeof(T2), new
object[] { o }); }));
}

I have attached a full example below.

Arne

=========================================================

using System;
using System.Collections.Generic;

namespace E
{
public class DTOEx
{
private int iv;
private String sv;
public DTOEx(int iv, string sv)
{
this.iv = iv;
this.sv = sv;
}
public int Iv
{
get
{
return iv;
}
set
{
iv = value;
}
}
public string Sv
{
get
{
return sv;
}
set
{
sv = value;
}
}
public override string ToString()
{
return "[DTO:" + iv + "," + sv + "]";
}
}
public class BOEx
{
private int iv;
private String sv;
public BOEx(int iv, string sv)
{
this.iv = iv;
this.sv = sv;
}
public BOEx(DTOEx o)
{
this.iv = o.Iv;
this.sv = o.Sv;
}
public int Iv
{
get
{
return iv;
}
set
{
iv = value;
}
}
public string Sv
{
get
{
return sv;
}
set
{
sv = value;
}
}
public override string ToString()
{
return "[BO:" + iv + "," + sv + "]";
}
}
public class Program
{
public static List<T2> DTO2BO<T1,T2>(List<T1> list, Predicate<T1>
p)
{
return list.FindAll(p).ConvertAll<T2>(new Converter<T1,
T2>(delegate(T1 o) { return (T2)Activator.CreateInstance(typeof(T2), new
object[] { o }); }));
}
public static void Main(string[] args)
{
List<DTOEx> dtoexlist = new List<DTOEx>();
dtoexlist.Add(new DTOEx(1, "A"));
dtoexlist.Add(new DTOEx(2, "BB"));
dtoexlist.Add(new DTOEx(3, "CCC"));
foreach(DTOEx o in dtoexlist)
{
Console.WriteLine(o);
}
List<BOEx> boexlist = DTO2BO<DTOEx,BOEx>(dtoexlist,
delegate(DTOEx o) { return o.Iv > 1; });
foreach(BOEx o in boexlist)
{
Console.WriteLine(o);
}
Console.ReadKey();
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top