[英]C# Method overloading using dynamic params
I'm trying to write a tool for serialization of values. 我正在尝试编写一个用于序列化值的工具。 And I was hoping to get some nice syntax working.....
我希望得到一些很好的语法工作.....
float f = 9999.0f;
ByteSerializer s = new ByteSerializer ();
s.Write(f);
Where the params of Write() could be anything and any number: Write()的参数可以是任何数字和任何数字:
public void Write (params dynamic[] objects)
{
for (int i =0;i<objects.Length;i++) {
byteList.AddRange (GetBytes (objects[i]));
}
}
GetBytes() should now be called according to the type of the object that was passed: 现在应该根据传递的对象的类型调用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);
}
But it will always go straight for the method that takes an object as parameter. 但是它总是直接用于将对象作为参数的方法。 I initially tried (params object[]) as method parameters and found this behaviour to be rather obvious.
我最初尝试(params object [])作为方法参数,发现这种行为相当明显。 But why does dynamic[] behave the same?
但为什么动态[]表现相同?
objects[i].GetType() reports a System.Single so what's going on here? objects [i] .GetType()报告一个System.Single,那么这里发生了什么? Is what I am trying to do just not possible?
我想做的就是不可能吗?
There is no reason this shouldn't work with dynamic
exactly as you described. 没有理由不应该像你描述的那样使用
dynamic
。 One of the primary features of the DLR is to do at runtime what would have been done at compile time if the types had been known then. DLR的主要功能之一是在运行时执行在编译时已完成的内容(如果已知类型)。 For example, the following program:
例如,以下程序:
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);
}
}
Produces the output: 产生输出:
Write string: a string
写字符串:一个字符串
Write byte: 1写字节:1
Write Single: 3单写:3
Write object: System.Object写对象:System.Object
Method overloading relies on knowing at compile time the types of all the arguments. 方法重载依赖于在编译时知道所有参数的类型。 Here, you can't know the argument types at compile time - because it's
dynamic
- so the compiler uses the lowest common type - which is object
. 在这里,您无法在编译时知道参数类型 - 因为它是
dynamic
- 因此编译器使用最低的公共类型 - 即object
。 The difference between object
and dynamic
is that dynamic
allows late binding syntax - but that doesn't help you here. object
和dynamic
之间的区别在于dynamic
允许后期绑定语法 - 但这对您没有帮助。
If you want to call GetBytes
for the correct types, you need to use reflection . 如果要为正确的类型调用
GetBytes
,则需要使用反射 。 Specifically, you want to use GetMethod to find an overload of GetBytes
that matches the type of each argument, and then call it. 具体来说,您希望使用GetMethod来查找与每个参数的类型匹配的
GetBytes
重载,然后调用它。 with Invoke . 使用Invoke 。 Something like this(not tested):
像这样的东西(未经测试):
byteList.AddRange (GetType()
.GetMethod("GetBytes", new Type[objects[i].GetType()])
.Invoke(null, new object[objects[i]]));
The dynamic
type behaves like the object
type. dynamic
类型的行为类似于object
类型。 The only difference is that for dynamic
the compiler does no type checking (so you can avoid compiler errors when working eg with COM). 唯一的区别是,对于
dynamic
,编译器不进行类型检查(因此在使用COM时可以避免编译器错误)。
What you intend, can be done anyway. 无论如何,你的意图是什么。 But you must take the long road and do an explicit typechecking/cast in your
for
loop (a long but simple switch
/ case
construct). 但是你必须走很长的路,并在你的
for
循环中做一个明确的类型检查/强制switch
(一个很长但很简单的switch
/ case
结构)。
HTH Thomas HTH托马斯
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.