C#params明显的编译器错误(C#5.0)

Ken*_*man 0 c# params c#-5.0

这是我认为昨天解决的一个帖子的后续内容.昨天我在以下情况下遇到了我的代码问题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    class Program
    {
        class Bar
        {
            int v;

            public Bar(int v) { this.v = v; }
            public override string ToString() { return v.ToString(); }
        }

        static void Main(string[] args)
        {
            Foo(1, 2, 3);
            Foo(new int[] { 1, 2, 3 });
            Foo(new Bar(1), new Bar(2), new Bar(3));
            Foo(new Bar[] { new Bar(1), new Bar(2), new Bar(3) });
            System.Threading.Thread.Sleep(20000);
        }

        static void Foo(params object[] objs)
        {
            Console.WriteLine("New call to Foo: ");
            foreach(object o in objs)
                Console.WriteLine("Type = " + o.GetType() + ", value = "+o.ToString());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你运行它,你可以看到最后一次调用Foo的问题.参数是向量的事实是"丢失"的.

那么....任何人都知道如何报告C#编译器错误?或者这会被视为反射错误?

(真是令人宽慰:我很沮丧地认为我浪费了时间来处理我自己的错误.实际上它毕竟是一个C#错误,我已经得到了证实!我们经常看到实际的C#编译器错误这几天?不常见......)

Ray*_*hen 18

C#4.0规范是这一切是如何发挥出非常明确.7.5.3.1表示如果一个函数params可以以正常形式(忽略params关键字)或扩展形式(使用params关键字)应用,则普通形式获胜.

假设Foo被声明为Foo(params object[] args),则该调用Foo(new Foobar[] {new Foobar(1), new Foobar(2), new Foobar(3)) });适用于正常形式,因为Foobar[]可以隐式转换为object[](6.1.6第5条).因此,使用正常形式并忽略展开形式.

(我假设C#5.0没有改变这部分语言.)


Chr*_*ain 7

希望这两个调用具有相同的功能 - params参数是被调用方法中的数组.乔恩斯基特在上一问题如的作品,因为INT的数组不是协变到对象的数组(因此被视为new Object[] { new Int[] {1,2,3} }),但在这个例子中FooBars数组协变到对象的数组,所以你的参数扩展到objs论证中.

所有事物的维基百科涵盖了这个确切的案例:协方差和逆变(计算机科学)

抱歉,但我确信这不是编译器错误.

编辑:

你可以实现你想要的:

Foo(new Object[] { new Bar[] { new Bar(1), new Bar(2), new Bar(3) } });
Run Code Online (Sandbox Code Playgroud)

NEW EDIT(其他作者):

或者只是使用:

Foo((Object)new Bar[] { new Bar(1), new Bar(2), new Bar(3) });
Run Code Online (Sandbox Code Playgroud)