繁体   English   中英

C#方法使用动态参数重载

[英]C# Method overloading using dynamic params

我正在尝试编写一个用于序列化值的工具。 我希望得到一些很好的语法工作.....

            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,那么这里发生了什么? 我想做的就是不可能吗?

没有理由不应该像你描述的那样使用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

方法重载依赖于在编译时知道所有参数的类型。 在这里,您无法在编译时知道参数类型 - 因为它是dynamic - 因此编译器使用最低的公共类型 - 即object objectdynamic之间的区别在于dynamic允许后期绑定语法 - 但这对您没有帮助。

如果要为正确的类型调用GetBytes ,则需要使用反射 具体来说,您希望使用GetMethod来查找与每个参数的类型匹配的GetBytes重载,然后调用它。 使用Invoke 像这样的东西(未经测试):

byteList.AddRange (GetType()
        .GetMethod("GetBytes", new Type[objects[i].GetType()])
        .Invoke(null, new object[objects[i]]));

dynamic类型的行为类似于object类型。 唯一的区别是,对于dynamic ,编译器不进行类型检查(因此在使用COM时可以避免编译器错误)。

无论如何,你的意图是什么。 但是你必须走很长的路,并在你的for循环中做一个明确的类型检查/强制switch (一个很长但很简单的switch / case结构)。

HTH托马斯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM