How to perform conversion from 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 ?
Regards
Two options:
- Use reflection to find the conversion and invoke it
- Use dynamic typing if you're using C# 4
Using reflection is likely to be painful. The dynamic approach is simpler if you can get away with it:
public static T GetValue<T>(dynamic d)
{
return (T) d;
}
That isn't a particularly drastic change to the signature, but if you wanted to keep it exactly the same, you could use:
public static T GetValue<T>(object o)
{
dynamic d = o;
return (T) d;
}
The reason the direct cast succeeds and the GetValue
method fails is because the direct cast method is using the explicitcast operator on the Mock<T>
type. This explicit cast operator is not available in the generic version because the C# compiler only sees T
and hence doesn't bind to the implicit conversion operator but instead chooses to do a CLR conversion.
The easiest way to get this to work is to add an interface to represent this conversion and then constraint 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();
}
How about this: var v2 = GetValue<string>((string)m);
?
This does not modify the GetValue method, rather casts the parameter sent into it. You retain your signature. The cast looks a bit redundant but you have to specify the type for GetValue anyway...
精彩评论