Cyber Defect
Cyber Defect

Reputation: 25

Generic Methods passing subClass to baseClass defined Method?

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

Answers (4)

Dzyann
Dzyann

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

Olivier Jacot-Descombes
Olivier Jacot-Descombes

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

Dennis
Dennis

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

Steve Czetty
Steve Czetty

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

Related Questions