Using Common Constraints with Type Values

I am experimenting with quick extension methods.

I have the following simple extension method for secure migration.

public static T As<T>(this Object source) where T : class { return source as T; } 

This worked fine, but when I tried to make it intuitive to use valuetypes with overload

  public static T As<T>(this ValueType source) where T : struct { return (T)source; } 

I ran into problems. The method resolution logic always selects the first method above and gives a syntax error (for sure) that the structure is not a class.

Is there a way to handle the above, or should I go along the path of eliminating the limitation when testing and processing all types in the same method?

==== Edit: answer questions ====

I am compiling this against a 3.5 framework. I'm not really trying to do anything, it's just an experiment with the above. My interest was aroused, and I threw some code together.

I am not particularly worried that it remains "safe." Here's how it started and can be kept safe by default () - but it's really not the focus of the question and the code to ensure "security" is simply unclear.

As for expressiveness, value.As<int>() is no more expressive than (int)value ; but why should the user of the method "just know" that he only works with reference types? My attempt to work with him was related more to the expected behavior of the method than to expressive writing.

The code snippet value.As<DateTime>() , gives the error "Type" System.DateTime "must be a reference type in order to use it as a parameter" T "in a generic type or method .... Like (object)". From the error message, I see that it allows the use of the top method above, since it requests a reference type.

+6
source share
1 answer

In .NET 4, the second overload is selected based on your sample code. (Also just tested on .NET 3.5, same result.)

 int myInt = 1; long myLong = myInt.As<long>(); // chooses ValueType version 

However, this only leads us to the place of the next crash. (T)source; leads to unacceptable cast exclusion. You can get around this by writing a method like

 public static T As<T>(this ValueType source) where T : struct { return (T)Convert.ChangeType(source, typeof(T)); } 

However, I wonder what you really want to achieve, because I do not see immediate benefits. (And in this regard, it is unsafe as a version of the source as T object.) For example, how

 long myLong = myInt.As<long>(); 

More expressive or easy to use than

 long myLong = (long)myInt; 
+3
source

Source: https://habr.com/ru/post/898772/


All Articles