5

给定以下 C# 代码:

var a = new[] {"123", "321", 1}; //no best type found for implicitly typed array

以及它在 VB.NET 中的对应物:

Dim a = {"123", "321", 1} 'no errors

看来 VB.NET 能够正确推断a=的类型Object(),而 C# 一直抱怨,直到将上述内容固定为:

var a = new object[] {"123", "321", 1};

对于上述场景,有没有办法在 C# 中自动推断类型?

编辑:在 C# 沙箱中使用不同类型后的有趣观察 - 如果所有元素在继承树中都有共同的父级,并且该父级不是Object或者如果元素可以转换为更广泛的类型(不丢失精度,例如Integer -> Double)。所以这两个都可以工作:

var a = new[] {1, 1.0}; //will infer double[]
var a = new[] {new A(), new B()}; //will infer A[], if B inherits from A

我认为这种行为在 C# 中是不一致的,因为所有类型都继承自Object,所以它与任何其他类型的祖先并没有太大的不同。这可能是一种设计,所以没有必要争论,但如果你知道原因,知道为什么会很有趣。

4

3 回答 3

9

不可以。C# 中的隐式类型数组要求数组初始值设定项中的表达式之一的类型是目标类型基本上,编译器试图准确地找到一种元素类型,以便所有其他类型都可以转换为它。

当然,您可以将任何元素转换object为:

var a = new[] { (object) "123", "321", 1}; 

...但是您也可以只使用显式类型的数组初始值设定项:

var a = new object[] {"123", "321", 1}; 

或者在您确实同时声明一个变量的情况下:

object[] a = {"123", "321", 1};
于 2012-11-20T22:44:46.097 回答
2

不可以。但是,您可以通过使用 Option Explicit On、Option Strict On 和 Option Infer Off 使 VB 的行为更像 C#。

最佳实践:期权推断

于 2012-11-20T22:45:46.160 回答
1

在 C# 中,您可以使用dynamicdynamic[] k = { "1", 2, "3" };

但是,它并没有完全模仿 VB 的行为。 dynamic[] k = { "1", "2", "3" }; 仍然给你一个对象数组,而在 VB 中你得到一个字符串数组。

而且当然:

dynamic[] k = { "1", "3", "3" };
int i = k[0].I_do_not_exist();

编译没有问题,但很可能会失败;)

于 2012-11-21T12:43:59.233 回答