|
 |
|
 |
|
Checking type and throwing exception?
|
|
On Fri, 15 May 2009 05:03:06 -0700, "Peter" <...@hotmail.com
Hi, I have a project where there are lots of classes implementing an
interface IGeneralConverter. This has one "Convert" method, which
converts an object of type ICalculationResult to a CalculationResult
object.
An example of one of these classes is below. The common thing for them
is that they check the actual type of the parameter, and if it does not
match the type the handle, then they throw an exception.
Personally I don't like this design, and would rather have coded these
"converters" so they could only accept the type they handled, but I
would like to hear the opinions of the C# experts here.
public class PowerSourceGenericConverter : IGeneralConverter
{
public CalculationResult Convert(ICalculationResult r)
{
if (!(r is PowerSource))
{
throw new ValidationException("CalculationResult is not of type
PowerSource");
}
PowerSource tmp = (PowerSource)r;
CalculationResult concreteResult = new CalculationResult();
// ... populate the concreteResult based on values from the
"PowerSource" ...
return concreteResult;
}
}
Where the interface is:
public interface IGeneralConverter
{
CalculationResult Convert(ICalculationResult r);
}
Based on another question I asked in this group a month or so ago, I
rewrote the "converter" classes in a generic fashion, which I thought
was much nicer, but as the project was already being finished, my
changes were not included. But wouldn't something like the following be
better?
public class PowerSourceGenericConverter :
IGeneralConverter<PowerSource{
public CalculationResult Convert(PowerSource r)
{
CalculationResult concreteResult = new CalculationResult();
// ... populate the concreteResult based on values from the
"PowerSource" ...
return concreteResult;
}
}
Where in this case, the interface is:
public interface IGeneralConverter<T{
CalculationResult Convert(T r);
}
Thanks,
Peter
|
| |
 |
|
 |
|
 |
|
 |
|
On Fri, 15 May 2009 10:07:14 -0700, "Peter Duniho" <...@nnowslpianmk.com
On Fri, 15 May 2009 05:03:06 -0700, Peter <...@hotmail.com
There's not enough information in your question to make any real
determination about the design. You left out the most interesting part,
which is what the definition of ICalculationResult and PowerSource are.
There's really no obviously positive benefit to a generic interface, given
that you already have a base interface that apparently is suitable for all
converters.
If the code calling the IGeneralConverter.Convert() method always is
compiled as using the actual type of the object, then a generic interface
may help you avoid having to check the type in the Convert() method. But
it's often useful to be able to code to the lowest-common denominator,
which in this case is the ICalculationResult interface. You sacrifice
that flexibility if you hard-code the "source" type into your converter,
both in terms of the compiled type of the source object, _and_ the
compiled type of the converter itself.
If you are sure you don't need that flexibility, then sure...I suppose a
generic interface might be an okay alternative. But there's nothing in
your post that shows me whether or not that's the case.
Pete
|
|
 |
|
 |
 |
|
 |
|
On Fri, 15 May 2009 14:52:48 -0700, "Peter" <...@hotmail.com
Hi, thanks for the answer. Interesting to hear that it could indeed be
fair enough to code it as it was done.
The ICalculationResult interface is:
public interface ICalculationResult
{
}
There are several implementations, which are nothing more than
data-bearing classes, with getters and setters with various data:
public class PowerSource : ICalculationResult
{
public int Material { get; set; }
public int Level { get; set; }
public int Brand { get; set; }
}
The converters simply read the data from the appropriate
ICalculationResult and put it in a CalculationResult object:
public class CalculationResult
{
public bool ResultOk { get; set; }
public string ResultMessage { get; set; }
public KeyValuePair<string, string}
/Peter
|
|
 |
|
 |
 |
|
 |
|
On Fri, 15 May 2009 17:43:11 -0500, "Ben Voigt [C++ MVP]" <...@newsgroups.nospam
Not necessarily. For example, with a single interface, you can have a
collection of IGeneralConverter objects. But if you want to collect
IGeneralConverter<Tcollection of object.
Most specifically, right now you can build a Dictionary<Type,
IGeneralConverterin a simple way. With the generic interface that wouldn't be possible.
Now it may make sense to have both (e.g. IComparable, IComparable<Tlet the base interface check the type and then delegate to the typesafe
implementation of the generic interface.
>
|
|
 |
|
 |
 |
|
 |
|
On Mon, 18 May 2009 05:24:52 -0500, Leon Lambert <...@inil.com
I generally use a pattern when dealing something like this. It would be
hard to explain this completely in this forum but maybe i can give you
enough to help.
When i need to convert one type to another i generally create an
enumeration to help. This enumeration represents how the caller wants
the conversion. In your case the caller would pass the enumerated value
to your Convert method. Internally then i would create an array of
helpers per concrete class. The helpers in the array would be a
hierarchy of worker classes that know the specifics of how to convert
from one concrete type to another.
The workflow would be then
1) Caller calls Convert with an enumerated value of the type of
conversion they want.
2) Convert algorithm would use the enumeration value to index an array
of helpers and call an convert helper method on the worker class.
This ends up pretty easy to add new conversion then. you just add to the
enumeration and just add a new conversion helper.
I know I didn't explain this very well but hopefully you can intuit
enough information to get the general concept.
Leon Lambert
>
|
|
 |
|
 |
|
|