说我有以下代码:
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
隐式转换为基础方法签名所需的类型。
答案 0 :(得分:1)
在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;
}
}
我一直想要让运行时只是弄清楚在运行时将MyField
转换成需要什么,但我想这不是什么大不了的事。如果有人想出更好的东西,请告诉我。我打算在此期间保持这个问题。
答案 1 :(得分:0)
您可能想要查看 Generics 。加上interface
可能会使动态使用更加可行。
public interface Helper <TInput, TOutput>
{
<TOutput> DoSomething(TInput input);
}
因此,当您将此interface
与类一起使用时,您将为输入和输出实现类型。这将给你相当大的灵活性,这应该避免你之前提到的那些cast
。一个小例子,我的意思是你可以根据需要调整它,但我仍然不明白你真正想做的事情。