在运行时隐式强制转换动态对象
本文关键字:转换 动态 对象 运行时 | 更新日期: 2023-09-27 18:17:16
假设我有以下代码:
class MyField : DynamicObject
{
public dynamic Value { get; private set; }
public override bool TryConvert(ConvertBinder binder, out object result)
{
result = binder.Type == Value.GetType() ? Value : null;
return result != null;
}
public MyField(dynamic v)
{
Value = v;
}
}
// ...
public static class Program
{
static void doSomething(ulong address) { /* ... */ }
public void Main(string[] args)
{
dynamic field = new MyField((ulong)12345);
doSomething(field); // fails as field is not a ulong.
doSomething((ulong)field); // succeeds as field can be casted to a ulong.
ulong field2 = field; // also succeeds
}
}
是否有办法使第一次呼叫doSomething
成功?我正在编写一个库来读取特定的文件格式,它使用序列化的c风格结构;读取文件需要读取这些保存的结构定义,然后用文件其余部分中包含的数据"填充"它们。我有一个"结构"DynamicObject
类(支持点符号访问)和一个"字段"DynamicObject
类,这主要是为了保存关于字段内容的附加信息;虽然我可能可以摆脱它,但它会使某些其他操作变得更加困难。我想做的只是"假装"MyField
是某种类型(好吧,技术上只是任何内置原语或原语数组,包括2D数组),并隐式地将其转换为该类型。但是,如果field
不匹配所需的类型,则运行时将无法尝试隐式地将field
转换为基础方法签名所需的类型。
根据Greg的回答,我想出了一个让运行时满意的解决方案。这不是我最初想要的,但似乎是最好的解决方案。
因为我已经在我的源代码中有一个大的if-else
树,其中我采用字节数组并将它们解释为实际的值类型,并且我当前的源代码确实使用底层泛型MyField<T>
,所以这工作得很好。我记不起当初为什么要把MyField
改成dynamic
了。
无论如何,这是一个改进的解决方案。
class MyField<T>
{
public dynamic Value { get; private set; }
public MyField(dynamic v) { Value = v; }
public static implicit operator T(MyField field)
{
return (T)field.Value;
}
}
我一直想要运行时只是找出它需要cast MyField
在运行时,但我想这不是一个大的交易。如果有人想出更好的办法,请告诉我。在此期间,我将保留这个问题。
您可能想要查看泛型。与interface
相结合可以使动态使用更加可行。
public interface Helper <TInput, TOutput>
{
<TOutput> DoSomething(TInput input);
}
因此,当您将此interface
与类一起使用时,您将为输入和输出实现类型。这将为您提供相当大的灵活性,这应该避免您之前提到的cast
。举个小例子,我的意思是你可以根据需要进行调整,但我还是不明白你到底想做什么