Multiple Type Constraint (OR)

Reading this , I found out that it is possible to allow a method to accept parameters of several types, making it a general method. In this example, the following code is used with a type constraint to ensure that "U" is an IEnumerable<T> .

 public T DoSomething<U, T>(U arg) where U : IEnumerable<T> { return arg.First(); } 

I found some more codes that allowed me to add some type restrictions, for example:

 public void test<T>(string a, T arg) where T: ParentClass, ChildClass { //do something } 

However, this code appears to ensure that arg must be both a ParentClass and a ChildClass . I want to say that arg can be of type ParentClass or ChildClass as follows:

 public void test<T>(string a, T arg) where T: string OR Exception { //do something } 

Your help is appreciated, as always!

+80
c # types asp.net-mvc-3
May 31 '12 at 12:46 a.m.
source share
3 answers

It's impossible. However, you can define overloads for certain types:

 public void test(string a, string arg); public void test(string a, Exception arg); 

If they are part of a generic class, they will be preferable to a generic version of the method.

+39
May 31 '12 at 12:50
source share

Botz's answer is 100% correct, here is a short explanation:

When you write a method (general or not) and declare the types of parameters that the method accepts, you define a contract:

If you give me an object that knows how to do a lot of things that Type T knows how to do, I can deliver either "a": the return value the type I declare, or 'b': some kind of behavior that this type of.

If you try to assign it several types at a time (using or) or try to force it to return a value that can be more than one type, the contract becomes fuzzy:

If you give me an object that knows how to jump with a rope or knows how to calculate pi by the 15th digit, I will return either an object that can go fishing, or maybe mix concrete.

The problem is that when you get into a method, you have no idea if they gave you IJumpRope or PiFactory . Also, when you go ahead and use the method (assuming you got it for magic compilation), you are not sure if you have Fisher or AbstractConcreteMixer . This is mostly confusing.

Solving your problem is one of two possibilities:

  • Define several methods that define each possible transformation, behavior, or something else. This is Botz's answer. In the programming world, this is called method overloading.

  • Define a base class or interface that knows how to do everything you need for the method and use one method of this type. This may include handling string and Exception in a small class to determine how you plan to map them to the implementation, but then everything is very simple and easy to read. I could come in four years and read your code and easily understand what is happening.

The choice you choose depends on how complex the choices are for 1 and 2, and how extensible it can be.

So, for your specific situation, I'm going to imagine that you are just pulling out a message or something from this exception:

 public interface IHasMessage { string GetMessage(); } public void test(string a, IHasMessage arg) { //Use message } 

Now you only need methods that convert string and Exception to IHasMessage. Very easy.

+16
May 31 '12 at 13:03
source share

If ChildClass means it is derived from ParentClass, you can simply write the following to accept both ParentClass and ChildClass;

 public void test<T>(string a, T arg) where T: ParentClass { //do something } 

On the other hand, if you want to use two different types without inheritance between them, you should consider types that implement the same interface,

 public interface ICommonInterface { string SomeCommonProperty { get; set; } } public class AA : ICommonInterface { public string SomeCommonProperty { get;set; } } public class BB : ICommonInterface { public string SomeCommonProperty { get; set; } } 

then you can write your general function as:

 public void Test<T>(string a, T arg) where T : ICommonInterface { //do something } 
+5
May 31 '12 at 12:55
source share



All Articles