3

My question is somewhat similar to Generic List of Generic Interfaces not allowed, any alternative approaches?

If I have an interface such as

public interface IPrimitive
{

}

public interface IPrimitive<T> : IPrimitive
{
     T Value { get; }
}

public class Star : IPrimitive<string> //must declare T here
{
    public string Value { get { return "foobar"; } }
}

public class Sun : IPrimitive<int>
{
    public int Value { get { return 0; } }
}

Then I have a list

var myList = new List<IPrimitive>();
myList.Add(new Star());
myList.Add(new Sun());

When looping through this list, how do I get the Value property?

foreach (var item in myList)
{
    var value = item.Value; // Value is not defined in IPrimitive so it doesn't know what it is
}

I'm not sure how this is possible.

Thanks, Rob

Community
  • 1
  • 1
QldRobbo
  • 129
  • 1
  • 8

4 Answers4

4

You can take advantage of dynamic:

foreach (dynamic item in myList) 
{ 
    var value = item.Value; 
} 

The dynamic type enables the operations in which it occurs to bypass compile-time type checking. Instead, these operations are resolved at run time

cuongle
  • 74,024
  • 28
  • 151
  • 206
3

You could do something like this:

public interface IPrimitive
{
    object Value { get; }
}

public interface IPrimitive<T> : IPrimitive
{
    new T Value { get; }
}

public class Star : IPrimitive<string> //must declare T here
{
    public string Value { get { return "foobar"; } }
    object IPrimitive.Value { get { return this.Value; } }
}

public class Sun : IPrimitive<int>
{
    public int Value { get { return 0; } }
    object IPrimitive.Value { get { return this.Value; } }
}

You're then able to get the value out as an object when you only have IPrimitive.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • 1
    thanks for your response, however this makes using a generic pretty pointless, I could just use the object value and get rid of all the generic stuff – QldRobbo Aug 08 '12 at 05:03
  • 1
    It doesn't make the generics pointless at all. All of your original goodness is there - this just provides a simple way to get the value out when you don't know the generic type parameter. It doesn't denigrate your existing code in any way. – Enigmativity Aug 08 '12 at 05:28
  • 1
    sorry, I wasn't clear, in my specific case it doesn't help me because I'm not using the interfaces for anything other than this list and to get the value. In other cases your answer might be appropriate. – QldRobbo Aug 08 '12 at 05:34
2

of course not, your value is going to be of different types..... so you will have to downcast to the real type to get at the different values.

Basically your interface is failing. Its not "A common interface" It's more a "similar interface"

If you don't want to do casting, then you will have to find an interface which is common to both of them.

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
0

You can move you Value property to base interface.

public interface IPrimitive
{
     object Value { get; }
}

How do you want to procced value in the loop it has different type?

user854301
  • 5,383
  • 3
  • 28
  • 37