Click here to Skip to main content
15,889,595 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello Everyone

I am trying to form a base class to manage values of value-types and instances of classes.

To do that I tried the following:

public interface IBase<T>
{
    T Value
    { get; set; }
}

public abstract class Base<T> : IBase<T>
{
    private T value;
    public T Value
    {
       get { return value; }
       set { this.value = value; }
    }
}

public class StringBase : Base<string>
{
  public StringBase(string value)
  {
     this.Value = value;
  }
}

public class IntBase : Base<int>
{
  public IntBase(int value)
  {
     this.Value = value;
  }
}

public class MyClassEntity : Base<MyAnyClass>
{
   public MyClassEntity(MyAnyClass instance)
   {
      this.Value = instance;
   }
}


then in some code I want to do this

StringBase sb = new StringBase("Test");
IntBase ib = new IntBase(3);

dreambaseIamlookingfor x = sb;
System.Diagnostics.Debug.WriteLine(x.Value);
x = ib;
x.Value = 30;
System.Diagnostics.Debug.WriteLine(x.Value);


For example I cannot do this also:
 List<dreambaseIamlookingfor> lst = new List<dreambaseIamlookingfor>();
lst.Add(sb);
lst.Add(ib);


Does it possible that I can form such a dream base ?
If it is, then what can be and how can be 'dreambaseIamlookingfor' class or interface ?

I do not know if covariance or contravariance will help me in this case ?

Thank you
Posted
Comments
Toli Cuturicu 11-Dec-10 7:53am    
Why?

Hi Andi.

I see your point, but being not much clear to me, the progress of C# and .NET and within the scope of my readings about covariance and contravariance I thought it could be possible.

It is really simple though if I do not mind to use generics at the very base of my class hierarcy. I could just change my IBase<T> to IBase and make this interface to get and set an Object value instead of T and I can convert this to T and vice versa. I tried to avoid this. I believe this could cause performance penalties. At the end I now know that it is unavoidable for me to use Object type.

Thanks and best regards,
Erhan
 
Share this answer
 
v2
Generics and polymorphism are two orthogonal concepts.

You try to use polymorphism where you have generic classes.
E.g. x.value is obviously not polymorphic since it has separate implementations depending on some generic types.

If you can afford to loose compile time type checks and are willing to pay the runtime overhead for reflection and if you are also willing to handle linking exceptions at runtime, then you could define x as dynamic and the list as List<dynamic>.

I would generally not advise that, though.

You should decide if you need polymorphism or if you need generics, but not both for your problem at hand.

If you want to have generics mixed with polymorphism, then for polymorphic access, you must only employ methods without generic types and no generic properties.

Andi

Edited Answer:
Example code that might show how you may employ extension methods for a kind of interface methods with generics. As you can see, polymorphism is broken since you need to know the type of the polymorphic object:

C#
public static class Extension
{
    public static bool Is<T>(this IBase obj) { return obj is Base<T>; }
    public static Base<T> As<T>(this IBase obj) { return (Base<T>)obj; }
}

public interface IBase
{
}

public class Base<T> : IBase
{
    public T Value { get; set; }
}

public class StrBase : Base<string>
{
}

public class IntBase : Base<int>
{
}

class Program
{
    static void Main(string[] args)
    {
        {
            StrBase sb = new StrBase();
            sb.Value = "abc";
            string s = sb.Value;
        }

        {
            IntBase ib = new IntBase();
            ib.Value = 123;
            int i = ib.Value;
        }

        {
            IBase obj = new IntBase();

            obj.As<int>().Value = 234;
            int i = obj.As<int>().Value;
        }

        {
            List<IBase> list = new List<IBase>();
            list.Add(new IntBase());

            list[0].As<int>().Value = 123;
            int i = list[0].As<int>().Value;
        }
    }
}
 
Share this answer
 
v4
Comments
Henry Minute 12-Dec-10 11:43am    
Andreas: In case you missed it, the OP has responded by adding an answer.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900