我正在尝试编写一个用于序列化值的工具。我希望得到一些很好的语法......
float f = 9999.0f;
ByteSerializer s = new ByteSerializer ();
s.Write(f);
Write()的参数可以是任何数字和任何数字:
public void Write (params dynamic[] objects)
{
for (int i =0;i<objects.Length;i++) {
byteList.AddRange (GetBytes (objects[i]));
}
}
现在应该根据传递的对象的类型调用GetBytes():
public byte[] GetBytes ( object v)
{
//Shouldn't actually do anything since it's a dummy
return new byte[0];
}
public byte[] GetBytes ( System.Single v)
{
//Why is this not called?
return BitConverter.GetBytes (v);
}
但是它总是直接用于将对象作为参数的方法。 我最初尝试(params object [])作为方法参数,发现这种行为相当明显。但为什么动态[]表现相同?
objects [i] .GetType()报告一个System.Single,那么这里发生了什么?我想做的就是不可能吗?
答案 0 :(得分:1)
没有理由这不应该与您描述的dynamic
完全一致。 DLR的主要功能之一是在运行时执行在编译时已完成的内容(如果已知类型)。例如,以下程序:
public class Program
{
public static void Main(string[] args)
{
WriteItems("a string", (byte)1, 3f, new object());
}
private static void WriteItems(params dynamic[] items)
{
foreach(dynamic item in items)
{
Write(item);
}
}
private static void Write(byte b)
{
Console.WriteLine("Write byte: {0}", b);
}
private static void Write(float f)
{
Console.WriteLine("Write Single: {0}", f);
}
private static void Write(string s)
{
Console.WriteLine("Write string: {0}", s);
}
private static void Write(object o)
{
Console.WriteLine("Write object: {0}", o);
}
}
产生输出:
写字符串:字符串
写字节:1
单写:3
写对象:System.Object
答案 1 :(得分:0)
方法重载依赖于在编译时知道所有参数的类型。在这里,你无法在编译时知道参数类型 - 因为它是dynamic
- 因此编译器使用最低的公共类型 - object
。 object
和dynamic
之间的区别在于dynamic
允许后期绑定语法 - 但这对您没有帮助。
如果您想针对正确的类型致电GetBytes
,则需要使用reflection。具体来说,您希望使用GetMethod来查找与每个参数的类型匹配的GetBytes
重载,然后调用它。与Invoke。这样的事情(未经测试):
byteList.AddRange (GetType()
.GetMethod("GetBytes", new Type[objects[i].GetType()])
.Invoke(null, new object[objects[i]]));
答案 2 :(得分:0)
dynamic
类型的行为类似于object
类型。唯一的区别是对于dynamic
,编译器不进行类型检查(因此在使用COM时可以避免编译器错误)。
无论如何,你的意图是什么。但是你必须走很长的路,在你的for
循环(一个冗长而简单的switch
/ case
构造)中进行明确的类型检查/强制转换。
HTH Thomas