Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excluding Types in the Generic Constraints (Possible?)

Is possible to exclude specific types from the set of possible types, that can be used in a generic parameter? If so how.

For example

Foo<T>() : where T != bool

would mean any type except for the type bool.

Edit

Why?

The following code is my attempt to enforce the negative constraint.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      var x1=Lifted.Lift("A");
      var x2=Lifted.Lift(true);
    }
    static class Lifted
    {
      // This one is to "exclude" the inferred type variant of the parameter
      [Obsolete("The type bool can not be Lifted", true)]
      static public object Lift(bool value) { throw new NotSupportedException(); }
      // This one is to "exclude" the variant where the Generic type is specified.
      [Obsolete("The type bool can not be Lifted", true)]
      static public Lifted<T> Lift<T>(bool value) { throw new NotSupportedException(); }
      static public Lifted<T> Lift<T>(T value) { return new Lifted<T>(value); }
    }

    public class Lifted<T>
    {
      internal readonly T _Value;
      public T Value { get { return this._Value; } }
      public Lifted(T Value) { _Value = Value; }
    }
  }
}

As you can see it involves a bit of faith in the overload resolution being correct, and bit of @jonskeet -esque evil code.

Comment out the section with deals with the inferred type example and it doesn't work.

It would be so much better to have the excluded generic constraint.

like image 764
Adam Speight Avatar asked May 17 '12 20:05

Adam Speight


People also ask

What are generic type constraints?

The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.

What does the generic constraint of type interface do?

Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.

What is generic type constraints in C#?

C# allows you to use constraints to restrict client code to specify certain types while instantiating generic types. It will give a compile-time error if you try to instantiate a generic type using a type that is not allowed by the specified constraints.

Which of the following generic constraints restricts the generic type parameter to an object of the class?

Value type constraint If we declare the generic class using the following code then we will get a compile-time error if we try to substitute a reference type for the type parameter.


1 Answers

Nope, you can't make one-off exclusions like that using type constraints. You can do it at runtime though:

public void Foo<T>()
{
     if (typeof(T) == typeof(bool))
     {
         //throw exception or handle appropriately.
     }
}
like image 69
vcsjones Avatar answered Sep 27 '22 20:09

vcsjones