5

I have seen similar questions asked and answered but I’m still struggling with my simple implementation. I want to be able to return a class property with a different return type. I then want to be able to use them all interchangeably in a collection.

public ClassInt
{
public int Id { get; set; }
public string MyValue { get; set; }
}

public ClassString
{
public int  Id { get; set; }
public int  MyValue { get; set; }
}

So the classes are the same with the exception of the return type on MyValue. This is what I got to so far:

public interface IBaseClass
{
    int Id { get; set; }
    object Value { get; set; }
}

public abstract class BaseClass <T> : IBaseClass
{
    public int Id { get; set; }
    public abstract T Value { get; set; }
}

public class ClassInt : BaseClass<int>
{
    private int _value;
    public override int Value
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value;
        }
    }
}

public class ClaseString : BaseClass<string>
{
    private string _value;
    public override string Value
    {
        get
        {
            return String.Format(“Hello: {0}”, _value);
        }
        set
        {
            _value = value;
        }
    }
}

To display the values:

List<IBaseClass> MyObjects = new List<IBaseClass>();

MyObjects.Add(new ClassString() { Id = 1, Name = "value 1", Value = "F1 String 1" });
MyObjects.Add(new ClassInt() { Id = 2, Name = "value 2", Value = 500 });

IBaseClass f0 = MyObjects[0];
IBaseClass f1 = MyObjects[1];

The issue now is that f0 and f1 do not have the Value property exposed.

Any suggestions or comments appreciated.

Thanks

Mike Bryant
  • 107
  • 1
  • 3
  • 4
    Make your `IBaseClass` generic: `IBaseClass` and change `object Value { get; set; }` into `T Value { get; set; }`? – CodeCaster Oct 11 '13 at 13:05
  • Are you going to need to set the value while working with IBaseClass objects? Not that that would make much sense :D – Jan Van Herck Oct 11 '13 at 13:09
  • @CodeCaster: he can't do that because he wants to use a List – Jan Van Herck Oct 11 '13 at 13:11
  • @Jan you're right. Then see also [List of generic interfaces](http://stackoverflow.com/questions/2045123/list-of-generic-interfaces): _"It's not clear how you'd want to use a collection of data elements without knowing their types..."_. – CodeCaster Oct 11 '13 at 13:15

1 Answers1

3

Give this a try.

public interface IBaseClass
{
    int Id { get; set; }
    object Value { get; set; }
}

public abstract class BaseClass<T> : IBaseClass
{
    public int Id { get; set; }

    public T Value { get; set; }

    object IBaseClass.Value
    {
        get { return Value; }
        set
        {
            // put some type checking and error handling here
            Value = (T)value;
        }
    }
}

public class ClassInt : BaseClass<int>
{
    // Properties specific for ClassInt, if you have any
    // (otherwise you don't even need this class anymore)
}
Jan Van Herck
  • 2,254
  • 17
  • 15
  • Ok I see what you did here with removing the I -> base -> concrete inheritance and made the abstract class and inheritance separate from each other. Is this a 'trick ' to make it work or is this a valid OO approach? I asking since as I see it the base class or the interface could change and the other would not know about it. Also by using object in the concrete class necessitates the use of manual validation which I would imagine should be done by the system if possible. – Mike Bryant Oct 11 '13 at 13:39
  • Ok tested it with some concrete classes and removed classes which did not have any implementation and all works fine. – Mike Bryant Oct 11 '13 at 19:55
  • A good example where two minds are better than one and criticism leads to better results. I'm much happier with my edited reply also. – Jan Van Herck Oct 11 '13 at 22:07