Search code examples
c#enumsinterfacenullable-reference-types

C# Interface Implementation Error when using nullable reference types


I'm having trouble with implementing an interface in C#. I have an interface IPreferencesWrapper<T> where T is an Enum. The interface has a Get method that should return a nullable T?.

Here's the interface:

public interface IPreferencesWrapper<T> where T : Enum
{
    T? Get(string preferenceName);
    void Set(string preferenceName, T value);
}

I'm trying to implement this interface in a class LanguagePreferencesWrapper:

public class LanguagePreferencesWrapper : IPreferencesWrapper<Language>
{
    public Language? Get(string preferenceName)
    {
        var languageString = Preferences.Get(preferenceName, default(string));
        return string.IsNullOrEmpty(languageString) ? null : (Language)Enum.Parse(typeof(Language), languageString);
    }

    public void Set(string preferenceName, Language language)
    {
        Preferences.Set(preferenceName, language.ToString());
    }
}

However, I'm getting an error that LanguagePreferencesWrapper does not implement interface member IPreferencesWrapper.Get(string). The error message says 'LanguagePreferencesWrapper.Get(string)' cannot implement 'IPreferencesWrapper.Get(string)' because it does not have the matching return type of 'Language'.

But the return typeof 'Get' is 'T?', so why is it expecting a return Type 'Language'


Solution

  • Currently your interface constrains T to be Enum or a type derived from it - but it doesn't constrain it to be a value type. Assuming you only ever want a wrapper for a concrete enum type, just add the struct constraint:

    public interface IPreferencesWrapper<T> where T : struct, Enum
    

    At that point the code will build, because the compiler will know that T? means Nullable<T> rather than "maybe the nullable reference type for T". (The introduction of nullable reference types has some "interesting" interactions with generics.)