Omicron
Omicron

Reputation: 53

calling derived methods on a baseclass collection

I have one abstract class named A, and other classes (B, C, D, E, ...) that implements A. My derived classes are holding values of different types. I also have a list of A objects.

    abstract class A { }
    class B : class A
    {
      public int val {get;private set;}
    }
    class C : class A
    {
      public double val {get;private set;}
    }
    class D : class A
    {
      public string val {get;private set;}
    }

    class Program
    {
        static void Main(string[] args)
        {
          List list = new List { new B(), new C(), new D(), new E() };
          // ... 

          foreach (A item in list)
          {
            Console.WriteLine(String.Format("Value is: {0}", item.val);
          }
        }
    }

...where the .val is not known by the base-class ofc.

How can i get this dynamic behaviour? I don't want to use getType in a long switch/if-statements.

Upvotes: 5

Views: 136

Answers (4)

jmcilhinney
jmcilhinney

Reputation: 54417

If val is not a member of the base class then you can't access it on a reference of that type. Those three derived classes may all have a member named val but it is NOT the same member so it cannot be treated like it is. What you could do is declare a generic class and make that val property of the generic type but then you couldn't create a List of that type. Basically, what you want to do is not possible. It's not based on inheritance and it's not based on generics. It sounds convenient but it's not logical.

Upvotes: 1

Nimmi
Nimmi

Reputation: 690

 abstract class A { public string val { get; set; } }
class B :  A
{
  public int val {get;private set;}
}
class C :  A
{
  public double val {get;private set;}
}
class D :  A
{
  public string val {get;private set;}
}

class Program
{
    static void Main(string[] args)
    {
        List<object> list = new List<object> { new B(), new C(), new D() };
      // ... 

      foreach (A item in list)
      {
        Console.WriteLine(String.Format("Value is: {0}", item.val));
      }
    }
}

Upvotes: 1

Imapler
Imapler

Reputation: 1422

If you just want to get the string representation of val i recoment overriding ToString in each of the sub classes

public override string ToString()
{
    return val.ToString();
}

either way if you want the data in a sub class you need to represent it in the base class as some type they all have in common (like object). and you could do it like this

abstract class A 
{
    public abstract object GetValue();
}
class B : class A
{
    public int val {get;private set;}
    public override object GetValue()
    {
        return val;
    }
}

Upvotes: 3

user1968030
user1968030

Reputation:

Try this:

using System;
using System.Collections.Generic;

abstract class A
{
    public abstract dynamic Val { get;   set; }

}
class B : A
{
    public override dynamic Val { get;  set; }
}
class C : A
{
    public override dynamic Val { get;  set; }
}
class D : A
{
    public override dynamic Val { get;  set; }
}

class Program
{
    static void Main(string[] args)
    {
        var list = new List<A> { new B(), new C(), new D() };
        // ... 

        foreach (A item in list)
        {
            Console.WriteLine(String.Format("Value is: {0}", item.Val));
        }
    }
}

Upvotes: 2

Related Questions