(object o...">

How to convert from an object reference

class Mock { public static explicit operator String(Mock s) { return "ok"; } } static T GetValue<T>(object o) { return (T)o; } Mock m = new Mock(); var v1 = (string) m; var v2 = GetValue<string>(m); // InvalidCastException is thrown. // How to modify GetValue method // internally, without changing its // signature, for this casting to work ? 

Hello

+4
source share
3 answers

Two options:

  • Use reflection to find the transformation and call it
  • Use dynamic typing if you are using C # 4

Using reflection is likely to be painful. A dynamic approach is easier if you can handle it:

 public static T GetValue<T>(dynamic d) { return (T) d; } 

This is not a particularly dramatic change in signature, but if you want to keep it exactly the same, you can use:

 public static T GetValue<T>(object o) { dynamic d = o; return (T) d; } 
+2
source

The reason the direct listing is performed and the GetValue method fails is because the direct casting method uses an explicit distribution operator such as Mock<T> . This explicit casting operator is not available in the general version because the C # compiler sees only T and therefore does not bind to the implicit conversion operator, but instead decides to do a CLR conversion.

The easiest way to get this to work is to add an interface to represent this transformation, and then restrict T to implement the interface

 interface IConvertToString { string Convert(); } public class Mock : IConvertToString { public string Convert() { return "ok"; } } public static T GetValue<T>(T o) where T : IConvertToString { return o.ConvertToString(); } 
+1
source

How about this: var v2 = GetValue<string>((string)m); ?

This does not change the GetValue method, but rather discards the parameter sent to it. You keep your signature. The listing looks a bit redundant, but you should still specify the type GetValue ...

0
source

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


All Articles