I have case where am given a collection of objects that all derive from the same base class. If I iterate over the collection and check each item's type, I can see that the object is of a derived type and then handle it accordingly. What I would like to know is if there is an easier way of performing the check for the derived type besides what I am already doing. Code repetition typically isn't required, so my current methodology seems a bit off to me.
class A {}
class B : A {}
class C : A {}
class D : C {}
class Foo
{
public List<A> Collection { get; set; }
}
class Bar
{
void Iterate()
{
Foo f = new Foo();
foreach(A item in f.Collection)
{
DoSomething(a);
}
}
void DoSomething(A a)
{
...
B b = a as B;
if(b != null)
{
DoSomething(b);
return;
}
C c = a as C;
if(c != null)
{
DoSomething(c);
return;
}
D d = a as D;
if(d != null)
{
DoSomething(d);
return;
}
};
void DoSomething(B a){};
void DoSomething(C a){};
void DoSomething(D a){};
}
I am working with a web service where every web service must have the same result type.
class WebServiceResult
{
public bool Success { get; set; }
public List<Message> Messages { get; set; }
}
class Message
{
public MessageType Severity { get; set; } // Info, Warning, Error
public string Value { get; set; } //
}
class InvalidAuthorization: Message
{
// Severity = MessageType.Error
// Value = "Incorrect username." or "Incorrect password", etc.
}
class InvalidParameter: Message
{
// ...
}
class ParameterRequired: InvalidParameter
{
// Severity = MessageType.Error
// Value = "Parameter required.", etc.
public string ParameterName { get; set; } //
}
class CreatePerson: Message
{
// Severity = MessageType.Info
// Value = null
public int PersonIdentifier { get; set; } // The id of the newly created person
}
The goal is that we can return as many different types of messages back to the client as we want. Instead of getting a single message per web service call, the callee can know about all of their mistakes/successes in a single trip and to eliminate string parsing specific information from the message.
I originally though about using generics, but since the web service could have varying message types, the collection was broadened to use the base message class.
It may be possible to move DoSomething to A and have each subclass provide their own implementation:
public abstract class A
{
abstract void DoSomething();
}
void Iterate()
{
Foo f = new Foo();
foreach(A item in f.Collection)
{
item.DoSomething();
}
}
An idea would be to use a generic constraint on your base class or an interface.
public class MyClass<T> where T : BaseClass, IInterface
{
public void executeCode<T>(T param) {};
}
So MyClass<T> takes only a certain type, executeCode will have an idea what methods are exposed and what operations can be performed on the data of the object passed.
This avoids the need to cast because you are specifying a contract that must be followed.
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