1

I'd like to define an generic interface that allows nullable value types (int?, double?, etc.) and class types (which can also be null). I do not want to allow a simple value type. Is there a way to do this?

bsh152s
  • 3,178
  • 6
  • 51
  • 77

3 Answers3

6

EDIT: Given the question title, I assume you want to constrain the type parameter to not be a non-nullable value type. It would probably be a good idea to specify that in the question body too.

No - there's no such constraint. In fact, both class and struct constraints prohibit arguments which are nullable value types.

You could potentially create an interface without a constraint, but only create two implementations:

interface IFoo<T> { }

class FooClass<T> : IFoo<T> where T : class {}

class FooNullableValue<T> : IFoo<Nullable<T>> where T : struct {}

That wouldn't stop anyone else from implementing IFoo<int> of course. If you can give us more background, we may be able to help more.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • The two implementations is exactly what we're currently doing. I just wasn't convinced that both were needed. I believed you have confirmed the need. – bsh152s Oct 05 '11 at 16:02
1

Yes, simply using no constraint allows you to specify any type:

public interface IAllowReferenceTypes<T>
{
   T GetValue();
}

public class SomeClass : IAllowReferenceTypes<Int32?>
{
   public Int32? GetValue() { return null; }
}

EDIT: Fixed.

Note: You ask for a constraint in your title, but in the body if your question you simply ask for an interface that allows both nullable value types and reference types.

Using no constraint accomplishes the latter. As Jon's answer points out, there is no way to use constraints guarantee that a type is nullable. You can, however, use no constraints and do checking for null ( or default(T) )

Daniel Schaffer
  • 56,753
  • 31
  • 116
  • 165
0

This may be what you're looking for.

Greg Dean's answer:


Change the return type to Nullable, and call the method with the non nullable parameter

static void Main(string[] args)
{
    int? i = GetValueOrNull<int>(null, string.Empty);
}


public static Nullable<T> GetValueOrNull<T>(DbDataRecord reader, string columnName) where T : struct
{
    object columnValue = reader[columnName];

    if (!(columnValue is DBNull))
        return (T)columnValue;

    return null;
}

Also, see the following MSDN article on generic interfaces: http://msdn.microsoft.com/en-us/library/kwtft8ak.aspx

Community
  • 1
  • 1
Polynomial
  • 27,674
  • 12
  • 80
  • 107
  • 1
    Please don't post links to version-specific MSDN articles unless the question is version-specific. – John Saunders Oct 05 '11 at 16:01
  • @JohnSaunders - Sorry, didn't realise I had. Just saw the relevance and posted it. – Polynomial Oct 05 '11 at 16:02
  • 1
    FYI, that's why not to post the old links. Readers get trapped in a maze of old links and don't even realize they're reading old information. – John Saunders Oct 05 '11 at 16:03
  • Yeah, I hadn't even noticed I'd done it until you pointed it out. It's relevant for now (VS2010) but it's not future-proof. – Polynomial Oct 05 '11 at 16:04
  • @Polynomial one word, "Hats". Besides your answer was among the low quality answers in the review Que, someone flagged it. – Sharp Edge Dec 16 '15 at 10:41