How to convert a specific type to a generic type

I've got the following classes:

  • Parameter.cs (generic type)
  • CurrentLod.cs (specific type, inherits from Parameter)

This is the current class definition for Parameter.cs

public abstract class Parameter<T> where T: IComparable{
     // class methods...
}

And then the class definition for CurrentLod.cs

public class CurrentLod : Parameter<String>{
     
     // Constructor
     public CurrentLod() : base()
}

Then, in a third file

new List<Parameter<IComparable>>() { new CurrentLod() }

The previous code won't compile, and the compiler shows the error message: "Cannot convert from CurrentLod to Parameter"

I believe it's got something to do with covariance and contravariance, but it's still not clear to me.


Solution 1:

Your List<T> is defined to accept any Parameter<IComparable>. CurrentLod is a specific type of Parameter<IComparable>, namely a Parameter<String>.

We might later define another type Foo : Parameter<Int32>, since Int32 also implements IComparable.

But what does it mean to add a Foo to a list of CurrentLods?

To address your question, you could create a non-generic base class or interface for your parameter type and use that as the type of your List, e.g.:

public abstract class Parameter
{
    // Common paramater operations/properties. This could be an interface.
}

public class Parameter<T> : Parameter where T : IComparable
{
    // Type-specific generic members.
}

public class Int32Parameter : Parameter<Int32>
{
    // Int32 Parameter implementation
}

public class StringParameter : Parameter<String>
{
    // String Parameter implementation
}

// This unit test will compile and pass
public class UnitTest1
{
    [Fact]
    public void Test1()
    {
        var l = new List<Parameter>();
        l.Add(new StringParameter());
        l.Add(new Int32Parameter());

        Assert.Equal(2, l.Count);
    }
}

Now the List is defined to contain a single, specific type. When you retrieve an item from the list, you'll need to test what its concrete type is and cast it appropriately.