传递基本类型集合时,C#方法选择选择对象而不是IEnumerable <object>

时间:2017-05-25 10:50:58

标签: c#

我有一个带有两个添加方法的对象:

lapply(split(df2[-1], as.character(df2$a)), function(x) df1[df1$y %in% unlist(x),])

public void Add(string keyName, object value)

如果你调用它并提供一个对象,它会调用第一个对象。如果你提供IEnumerable,它会调用第二个。但是,如果你提供一个主要类型的IEnumerable,它会调用第一个。

有没有办法让c#选择第二种方法并将其打包而不是将数组视为对象?

如果不是,我想我会先检查第一个add方法,看看它是否是一个基本类型,并强制它调用第二个方法。

2 个答案:

答案 0 :(得分:7)

您可以使用泛型。如果您将第二种方法更改为:

public void Add<T>(string keyName, IEnumerable<T> values)
{

}

然后,如果它是IEnumerable<T>(例如IEnumerable<int>),那么它将使用泛型方法。

值得注意的是IEnumerable<T>IEnumerable<object>并不完全相同,所以如果您需要它是IEnumerable<object>,您需要IEnumerable<object> obList = values.Cast<object>();之类的内容{1}}

答案 1 :(得分:3)

添加@Chris答案并解释为什么它不适用于您的方式。 IEnumerable<T>定义如下:

public interface IEnumerable<out T>

其中out表示类型T是协变的,这反过来意味着您可以在其中使用子类型。在您的情况下,这意味着您可以使用从object继承的任何类型,其中IEnumerable<object>符合预期,例如IEnumerable<string>。但是那些协方差修饰符(out \ in)不适用于值类型(结构)。这意味着IEnumerable<string>可转换为IEnumerable<object>,但IEnumerable<int>不可转换为IEnumerable<int>。所以编译器不能选择第二次重载,因为它不会编译。

解决问题的正确方法是使用泛型(您也可以使用en.Cast<object>()明确地投射Queue<Task>)。