C#泛型方法参数PARAMS错误? [英] C# method generic params parameter bug?

查看:283
本文介绍了C#泛型方法参数PARAMS错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好像没有在C#编译器中的错误/不一致我看来,我



这工作正常(第一种方法被调用):

 公共无效的someMethod(字符串消息,对象数据); 
公共无效的someMethod(字符串消息,params对象[]数据);

// ...
的someMethod(呜呼项目);



然而,这使调用如下方法之间暧昧错误:

 公共无效的someMethod&放大器; LT; T&放大器; GT;(字符串消息,T的数据); 
公共无效的someMethod&放大器; LT; T&放大器; GT;(字符串消息,则params T []数据);

// ...
的someMethod(呜呼(T)项目);



我可以只使用dump第一种方法完全,但由于这是一个非常性能敏感图书馆第一种方法将使用大约75%的时间,我宁愿不总是换东西在一个数组和实例化一个迭代器,如果只有一个项目去了一个foreach。


$ b $ :b

分裂成不同的命名方法,将凌乱的最好IMO



思考



编辑?



我猜安德鲁可能是到的东西。



完整的示例:

 公共静态类StringStuffDoer 
{
公共静态字符串的ToString&放大器; LT; T&放大器; GT;(T ITEM1,T ITEM2)
{
返回item2.ToString()+ item1.ToString();
}

公共静态字符串的ToString&放大器; LT; T&放大器; GT;(T项目,则params T []项目)
{
StringBuilder的建设者=新的StringBuilder() ;

的foreach(T CURRENTITEM中的项目)
{
builder.Append(currentItem.ToString());
}

返回item.ToString()+ builder.ToString();
}

公共静态无效CallToString()
{
的ToString(someString,NULL); // FAIL
的ToString(someString,另一个字符串); // SUCCESS
的ToString(someString(串)NULL); // SUCCESS
}
}



我仍然认为这是奇怪的是,需要投 - 呼叫一点也不含糊。它的工作原理,如果你用绳子或对象或任何非泛型类型替换T,那么,为什么不是为通用工作?它正确地发现了两种可能的匹配方法,所以我认为,在规范中,则应该选择如果可能的话,不使用参数的方式之一。 。纠正我,如果我错了这里。



(不那么)最后更新:



对不起,带你这个tyraid家伙,我似乎一直盯着这太长了......太多看仿制药,而params了一个晚上。 ;非通用版本抛出暧昧的错误,以及,我只是方法签名关在我的样机测试



REAL最后更新:



好吧,这就是为什么这个问题并没有在我的非通用测试显示出来。我使用对象作为类型参数。的someMethod(对象)和的someMethod(params对象[])不要扔了不明确的错误,我想空被自动转换为对象。 。奇怪有点我会说,但有些可以理解的,也许



所以,奇怪的是,这一呼吁没有工作:

 的someMethod<对象>(someMessage,NULL); 


解决方案

似乎为我工作,是剩下的代码如下所示

 类TestThing< T> 
{
公共无效的someMethod(字符串消息,T数据)
{
Console.WriteLine(第一);
}
公共无效的someMethod(字符串消息,则params T []数据)
{
Console.WriteLine(第二);
}
}


类节目
{
静态无效的主要(字串[] args)
{
VAR项目=新的对象();
变种test_thing =新TestThing<对象>();
test_thing.SomeMethod(呜呼项目);
test_thing.SomeMethod(呜呼项目,项目);

到Console.ReadLine();
}
}

在.NET 3.5和产出编译罚款第一然后第二在运行时。您正在使用哪个版本/定位?



修改



这是问题的上面的代码编译器不能告诉什么类型的是。这是同样有效假定它是一个字符串或字符串数​​组,因此它为什么不明确的时候正好空,而不是模棱两可的,当你明确投它(即你告诉编译器应该如何处理)。



更新




同样可以主张
的someMethod(字符串,字符串)和
的someMethod(字符串,则params字符串[]),
但它的工作原理




其实,没有事实并非如此。你得到同样的暧昧方法的问题。

 公共静态字符串TypedToString(字符串项目1,串ITEM2)
{
返回;
}

公共静态字符串TypedToString(字符串项目1,PARAMS字符串[]项目)
{
返回;
}

公共静态无效CallToString()
{
TypedToString(someString,NULL); // FAIL
}


I appears to me as though there is a bug/inconsistency in the C# compiler.

This works fine (first method gets called):

public void SomeMethod(string message, object data);
public void SomeMethod(string message, params object[] data);

// ....
SomeMethod("woohoo", item);

Yet this causes "The call is ambiguous between the following methods" error:

public void SomeMethod&lt;T&gt;(string message, T data);
public void SomeMethod&lt;T&gt;(string message, params T[] data);

// ....
SomeMethod("woohoo", (T)item);

I could just use the dump the first method entirely, but since this is a very performance sensitive library and the first method will be used about 75% of the time, I would rather not always wrap things in an array and instantiate an iterator to go over a foreach if there is only one item.

Splitting into different named methods would be messy at best IMO.

Thoughts?

EDIT:

I guess Andrew might be onto something.

Full example:

public static class StringStuffDoer
{
    public static string ToString&lt;T&gt;(T item1, T item2)
    {
        return item2.ToString() + item1.ToString();
    }

    public static string ToString&lt;T&gt;(T item, params T[] items)
    {
        StringBuilder builder = new StringBuilder();

        foreach (T currentItem in items)
        {
            builder.Append(currentItem.ToString());
        }

        return item.ToString() + builder.ToString();
    }

    public static void CallToString()
    {
        ToString("someString", null); // FAIL
        ToString("someString", "another string"); // SUCCESS
        ToString("someString", (string)null); // SUCCESS
    }
}

I still think it is odd that the cast is needed - the call is not ambiguous. It works if you replace T with string or object or any non-generic type, so why wouldn't it work for the generic? It properly finds the two possible matching methods, so I believe that by the spec, it should pick the one that doesn't use params if possible. Correct me if I'm wrong here.

(NOT SO) FINAL UPDATE:

Sorry for taking you guys on this tyraid, I've apparently been staring at this too long...too much looking at generics and params for one night. The non-generic version throws the ambiguous error as well, I just had the method signature off in my mockup test.

REAL FINAL UPDATE:

Okay, this is why the problem didn't show up in my non-generic test. I was using "object" as the type parameters. SomeMethod(object) and SomeMethod(params object[]) do NOT throw the ambiguous error, I guess "null" automatically gets cast to "object". A bit strange I'd say, but somewhat understandable, maybe.

So, oddly enough, this call DOES work:

SomeMethod<object>("someMessage", null);

解决方案

Seems to work for me, does the rest of your code look like the following?

class TestThing<T>
{
    public void SomeMethod(string message, T data)
    {
        Console.WriteLine("first");
    }
    public void SomeMethod(string message, params T[] data)
    {
        Console.WriteLine("second");
    }
}


class Program
{
    static void Main(string[] args)
    {
        var item = new object();
        var test_thing = new TestThing<object>();
        test_thing.SomeMethod("woohoo", item);
        test_thing.SomeMethod("woohoo", item, item);

        Console.ReadLine();
    }
}

Compiles fine on .NET 3.5 and outputs "first" and then "second" when run. Which version are you using/targeting?

EDIT

The issue from your code above is that the compiler can't tell what type null is. It is equally valid to assume that it is a string or an array of strings, hence why it is ambiguous when just null and not ambiguous when you specifically cast it (i.e. you're telling the compiler how it should be treated).

UPDATE

"The same can be argued for SomeMethod(string, string) and SomeMethod (string, params string[]), yet it works"

Actually, no it doesn't. You get the same ambiguous method problem.

public static string TypedToString(string item1, string item2)
{
  return "";
}

public static string TypedToString(string item1, params string[] items)
{
  return "";
}

public static void CallToString()
{
  TypedToString("someString", null); // FAIL
}

这篇关于C#泛型方法参数PARAMS错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆