Generic type checking

前端 未结 8 1388
既然无缘
既然无缘 2020-12-22 17:10

Is there a way to enforce/limit the types that are passed to primitives? (bool, int, string, etc.)

Now, I know you can limit the generic typ

相关标签:
8条回答
  • 2020-12-22 17:58

    Pretty much what @Lars already said:

    //Force T to be a value (primitive) type.
    public class Class1<T> where T: struct
    
    //Force T to be a reference type.
    public class Class1<T> where T: class
    
    //Force T to be a parameterless constructor.
    public class Class1<T> where T: new()
    

    All work in .NET 2, 3 and 3.5.

    0 讨论(0)
  • 2020-12-22 17:59

    If you can tolerate using factory methods (instead of the constructors MyClass you asked for) you could always do something like this:

    class MyClass<T>
    {
      private readonly T _value;
    
      private MyClass(T value) { _value = value; }
    
      public static MyClass<int> FromInt32(int value) { return new MyClass<int>(value); }
      public static MyClass<string> FromString(string value) { return new MyClass<string>(value); }
      // etc for all the primitive types, or whatever other fixed set of types you are concerned about
    }
    

    A problem here is that you would need to type MyClass<AnyTypeItDoesntMatter>.FromInt32, which is annoying. There isn't a very good way around this if you want to maintain the private-ness of the constructor, but here are a couple of workarounds:

    • Create an abstract class MyClass. Make MyClass<T> inherit from MyClass and nest it within MyClass. Move the static methods to MyClass. This will all the visibility work out, at the cost of having to access MyClass<T> as MyClass.MyClass<T>.
    • Use MyClass<T> as given. Make a static class MyClass which calls the static methods in MyClass<T> using MyClass<AnyTypeItDoesntMatter> (probably using the appropriate type each time, just for giggles).
    • (Easier, but certainly weird) Make an abstract type MyClass which inherits from MyClass<AnyTypeItDoesntMatter>. (For concreteness, let's say MyClass<int>.) Because you can call static methods defined in a base class through the name of a derived class, you can now use MyClass.FromString.

    This gives you static checking at the expense of more writing.

    If you are happy with dynamic checking, I would use some variation on the TypeCode solution above.

    0 讨论(0)
提交回复
热议问题