Moving between value types in a class using generics

This section features (.NET 2.0):

public void AttachInput<T>(T input) where T : struct { if (input is int) { Inputs.Add((int)input); } } 

The compiler shows the error "Unable to convert type" T "to" int ".
So, I used Convert.ToInt32() , which worked, but does it make an input box to an object? Is there a better solution? Thanks

Edit1: filmed unnecessary material related to the question

Edit2: If you look in more detail in generics, it seems to me that Convert.ToInt32 , when T is already an int, there is no box for the object, and its int overload is the one that is called.

If true, Convert methods seem to me the best option at the moment.

+6
generics c #
source share
1 answer

For type safety and box avoidance, the only option is to specifically overload the input type int :

 public void AttachInput(int input) { Inputs.Add(input); } 

Update:

The OP updated the question using theory:

Taking a deeper look at generics, it seems to me that Convert.ToInt32, when T is already an int, does not box for an object and its int overload is one of which is called.

This is wrong, and a simple test can demonstrate it. Suppose we write our own set of overloads only to determine which one is being called:

 public static class OverloadTest { public static void Foo(int x) { Console.WriteLine("Foo(int)"); } public static void Foo(bool x) { Console.WriteLine("Foo(bool)"); } public static void Foo(object x) { Console.WriteLine("Foo(object)"); } } 

Now we will write a general method for modeling what is asked in the question:

 static void CallTheRightFoo<T>(T value) where T : struct { OverloadTest.Foo(value); } 

The theory is that since the CLR / JIT will create a specific version of the method for each type of value, it can choose a specific overload for int as it becomes available.

So here is the test:

 struct Test { } // in order to test a user-defined value type static void Main(string[] args) { CallTheRightFoo(1); CallTheRightFoo(true); CallTheRightFoo(new Test()); } 

Output:

 Foo(object) Foo(object) Foo(object) 

To associate this with Convert.ToInt32 , from your shared code you will always call the overload that takes object , and so the value will be put in a box and then should be unpacked inside Convert.ToInt32 (which should also check what type it is first).

While repeating the important point behind all of this: while boxing / unpacking is more expensive compared to not doing it, it is quite likely to be worth little compared to any real work your code does. Therefore, I would not worry too much about the cost of this until you can prove that this is a genuine burden on a realistic model of an application using your library.

+5
source share

All Articles