Suppose I want to parse some xml into a strongly-typed class. When I get the xml, I don't know if it should be type A or type B until I crack it open and take a look. I could take a look, and return an enum like this:
BaseType x = null;
TypeInfoEnum typeInfo = BaseType.GetTypeInfo(xml);
if(typeInfo == TypeInforEnum.TypeA)
{
x = BaseType.ParseXmlToTypeA(xml);
// do other work on Type A
}
else if(typeInfo == TypeInfoEnum.TypeB)
{
x = BaseType.ParseXmlToTypeB(xml);
// do other work on Type B
}
Or I could just handle the Parsing in one method and check the type:
BaseType x = BaseType.ParseXml(xml);
if(x.GetType() == typeof(TypeA))
{
// do work on Type A
}
else if(x.GetType() == typeof(TypeB))
{
// do work on Type B
}
Just wanting to get some others' thoughts from a design stand-point which you prefer. Right now, the details aren't very important. I'm just creating 2 different types from a single XML source, based on what's in the xml. Nothing complicated.
UPDATE:
Thanks for the answers so far. The types aren't really important here, but as an example, the class hierarchy might look like this:
class BaseType
{
public string CommonData { get; set; }
}
class TypeA : BaseType
{
public string TypeASpecificData { get; set; }
}
class TypeB : BaseType
{
public string TypeBSpecificData { get; set; }
}
Since this functionality will be rolled into an assembly that others will use, I liked the first option using an Enum because it seems awkward to have users of an API check the type of something, i.e. using an Enum seems more semantically thorough.
In the first option, you are essentially duplicating the information (type + enum) for no obvious benefit. Thus, given these two options, I'd choose the second one, although I'd prefer the more idiomatic is instead of the GetType comparison:
BaseType x = BaseType.ParseXml(xml);
if(x is TypeA)
{
// do work on Type A
}
else if(x is TypeB)
{
// do work on Type B
}
You might, however, consider a third option:
BaseType x = BaseType.ParseXml(xml);
x.DoWork();
with DoWork being an abstract method of BaseType which is overridden in TypeA and TypeB:
public abstract class BaseType
{
public abstract void DoWork();
}
public class TypeA : BaseType
{
public override void DoWork() {
// do work on Type A
}
}
public class TypeB : BaseType
{
public override void DoWork() {
// do work on Type B
}
}
What you need to do is to have 2 different methods - one that handles type A and another that handles type B:
public void DoWork(A a) { .. }
public void DoWork(B b) { .. }
And then you just send the instance to doWork. This will cause your code to do exactly what needs to be done without any type checks:
BaseType x = BaseType.ParseXml(xml);
DoWork(x);
Another option is to have the method DoWork implemented in both classes:
public abstract class BaseType {
public abstract void DoWork();
}
public class A: BaseType {
public void DoWork() { ... }
}
public class B: BaseType {
public void DoWork() { ... }
}
And then your parsing would look like:
BaseType x = BaseType.ParseXml(xml);
x.DoWork();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With