Reputation: 25
QUESTION IS CLARIFIED new thread : subclass properties accessed in generic method with superclass input
I have a base class A
subClasses B, C, and D inherit from A.
Each subClass has 3 subClasses a, b, and c.
a, b, and c have a list of unique properties.
However, now I want to build a generic function to access those properties, so how would I do this without switching on Type?
Clarification : I do not want a : B to have abstract C methods/properties
Example:
public void Method(A a){
if(a.isSubClassOf(B))
{Console.WriteLine(a.BaProperty);}
if(a.isSubClassOf(C))
{Console.WriteLine(a.CbProperty);}
if(a.isSubClassOf(D))
{Console.WriteLine(a.DcProperty);}
}
Upvotes: 1
Views: 832
Reputation: 5208
It depends greatly in what you really want to achieve. In some cases what Steve Czetty suggests is the best option.
In others you could just keep all the properties different and have a virtual method in the base class that returns for example in this case a "string" that you can then write in the console or anything you wish.
Edit: You could override ToString as Olivier suggested. But only if you feel what yo are going to retun is the "String representation of the object".
public abstract class A { public string PropertyA { get; set; }
public virtual string GetString() //
{
return PropertyA;
}
}
public class B:A
{
public string PropertyB { get; set; }
public override string GetString()
{
return PropertyB;
}
}
public class C:A
{
public string PropertyC { get; set; }
public override string GetString()
{
return string.Format("{0} - {1}", base.GetString(), PropertyC) // for example if you wanted to do something more complex
}
}
Now if what you need can not be solved like this, you could cast as Dennis Suggested.
There is another posibility: you could use the visitor pattern. Here you can find several ways to implement it.
Just so you have an idea you would wind up having a class similar to this: (it will depend on what you really want to achieve) You have to implement some other basic things (interface and some methods), but from a Reference to the base class you will be able to call the corresponding "Visit" method easily. There is a lot of detail in the link i added.
class ClassicVisitor : IAVisitor
{
public string SuperComplexStringResult { get;set; }
public void Visit(B b) { SuperComplexStringResult = String.Format("Super Complex Stuff + {0}", b.PropertyB); }
public void Visit(C c) { SuperComplexStringResult = String.Format("Super Complex Stuff + {0}", c.PropertyC); }
}
Upvotes: 0
Reputation: 112324
An elegant solution is to override ToString
public abstract class A { }
public class B : A {
public int b { get; set; }
public override string ToString()
{
return b.ToString();
}
}
// Do the same with C and D ....
A[] array = new A[] { new B(), new C(), new D() };
foreach (A a in array) {
Console.WriteLine(a);
}
Note that Console.WriteLine
does not need to know about a special method or property in A
. It also works for types not deriving from A
.
Upvotes: 0
Reputation: 37770
You can't define a member in derived class and access it via the reference to base class without casting to derived class:
class A {}
class B
{
public int i;
}
A a = new B();
a.i = 0; // error
((B)a).i = 0; // OK
Either declare virtual property in any of base types in your hierarchy, or use casting to the concrete derived type. Of course, in the second case your method doesn't make any sense.
Upvotes: 1
Reputation: 6228
Typically, you would use a virtual
or abstract
method defined in A
and overridden in the subclasses.
public abstract class A
{
protected abstract PropertyType PropertyValue {get;}
public void Method()
{
Console.WriteLine(PropertyValue);
}
}
public class B : A
{
protected override PropertyType Property { get { return PropertyType.B; } }
}
// etc...
Upvotes: 0