1

I've read several of the other questions on the topic of nullable types in generics and I still don't understand why MinMaxBase<T> and MyIntDecl compile and YourIntDecl doesn't. The compiler error is:

'YourIntDecl' does not implement interface member 'IMinMaxDecl.MinValue'. 'YourIntDecl.MinValue' cannot implement 'IMinMaxDecl.MinValue' because it does not have the matching return type of 'short'.

Without the IComparable constraint public class YourIntDecl : IMinMaxDecl<Int16?> compiles (notice the nullable Int16 type param), but with the constraint I get this error:

The type 'short?' cannot be used as type parameter 'T' in the generic type or method 'IMinMaxDecl'. The nullable type 'short?' does not satisfy the constraint of 'System.IComparable'. Nullable types can not satisfy any interface constraints.

What is the correct solution if I can't inherit from MinMaxBase because I need to have another base class?

public interface IMinMaxDecl<T> where T : IComparable
{
    T? MinValue { get; set; } // needs to be nullable because it is optional
    T? MaxValue { get; set; } // needs to be nullable because it is optional
}

public abstract class MinMaxBase<T> : IMinMaxDecl<T> where T : IComparable
{
    public T? MinValue { get; set; }
    public T? MaxValue { get; set; }
}

public class MyIntDecl : MinMaxBase<Int16>; // compiles fine

public class YourIntDecl : IMinMaxDecl<Int16>
{
    public Int16? MinValue { get; set; }
    public Int16? MaxValue { get; set; }
}
2
  • even if you could inherit from MinMaxBase, you are still not getting what you'd expect -> test whether MyIntDecl.MinValue is Int16? -> it's not. It's Int16 Commented Jun 3 at 1:23
  • 1
    Why does MinValue and MaxValue need to be optional? Just don't implement the interface if you don't have a min / max. But the actual problem is that T? means different things to classes and structures. If you don't specify class / struct in your where then it behaves as if it is a class. see learn.microsoft.com/en-us/dotnet/csharp/programming-guide/… Commented Jun 3 at 5:01

2 Answers 2

1

I'm not sure why this is but I think you need a version of the interface for value types and another version for reference types (the nullable thing in C# is kind of half-baked).

I.e., this interface works:

    public interface IMinMaxDecl<T> where T : struct, IComparable
Sign up to request clarification or add additional context in comments.

Comments

0
public class YourIntDecl : IMinMaxDecl<Int16>
{
    public Int16? MinValue { get; set; }
    public Int16? MaxValue { get; set; }
}

YourIntDecl : IMinMaxDecl<Int16?> Should fix it no? You are telling the generic type it Must be of type Int16 that doesn't allow null. But the type expected is a nullable type.

The reason the abstract class works, I think, is because the abstract comes with a base implementation of Int16? While the interface has no inherent properties. It can only force your Implemention to have a property of type T. Which you provide as Int16 non nullable.

In the non compiling example, you are in fact NOT, abiding by the interface contract.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.