gpt4 book ai didi

c# - 默认参数和泛型的方法解析问题

转载 作者:可可西里 更新时间:2023-11-01 08:29:37 24 4
gpt4 key购买 nike

使用 .NET 4,我对编译器无法解析下面示例中的第一个方法调用感到困惑。

using System;

namespace MethodResolutionTest
{
class Program
{
static void Main(string[] args)
{
NonGeneric foo = null;

// ambiguous
foo.Ext1(x => new NonGeneric());

// resolves to first Ext1
foo.Ext1(x => new NonGeneric(), 1);


// resolves to first Ext2
foo.Ext2(x => new NonGeneric());

// resolves to first Ext2
foo.Ext2(x => new NonGeneric(), 1);

// resolves to second Ext2
foo.Ext2(x => "foo");

// resolves to second Ext2
foo.Ext2(x => "foo", 1);


// resolves to first Ext3
foo.Ext3(x => new NonGeneric());

// resolves to first Ext3
foo.Ext3(x => new NonGeneric(), 1);

// resolves to second Ext3
foo.Ext3(x => "foo");

// resolves to second Ext3
foo.Ext3(x => "foo", 1);
}
}

public class NonGeneric
{
}

public class Generic<T> : NonGeneric
{
}

public static class Extensions1
{
public static NonGeneric Ext1(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext, int i = 0)
{
return null;
}

public static Generic<TNext> Ext1<TNext>(this NonGeneric first, Func<NonGeneric, TNext> getNext, int i = 0, string s = null)
{
return null;
}
}

// only difference between Extensions2 and Extensions1 is that the second overload no longer has a default string parameter
public static class Extensions2
{
public static NonGeneric Ext2(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext, int i = 0)
{
return null;
}

public static Generic<TNext> Ext2<TNext>(this NonGeneric first, Func<NonGeneric, TNext> getNext, int i = 0)
{
return null;
}
}

// Extensions3 explicitly defines an overload that does not default the int parameter
public static class Extensions3
{
public static NonGeneric Ext3(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext)
{
return Ext3(first, getNext, default(int));
}

public static NonGeneric Ext3(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext, int i = 0)
{
return null;
}

public static Generic<TNext> Ext3<TNext>(this NonGeneric first, Func<NonGeneric, TNext> getNext, int i = 0)
{
return null;
}
}
}

任何人都可以阐明这一点吗?我怀疑除了修改我的 API 以帮助编译器(根据上面的 Extensions3)之外我真的没有前进的道路,但如果有更简单/更好的方法那么我很乐意听到了。

最佳答案

这是不明确的,因为在第二个 Ext1 扩展方法中有两个可选参数。因为在第一次调用中省略了两个参数,所以编译器不知道您要使用哪个。

来自 C# 4.0 Language Specification :

§7.5.3 过载决议:

Given the set of applicable candidate function members, the best function member in that set is located. If the set contains only one function member, then that function member is the best function member. Otherwise, the best function member is the one function member that is better than all other function members with respect to the given argument list, provided that each function member is compared to all other function members using the rules in §7.5.3.2. If there is not exactly one function member that is better than all other function members, then the function member invocation is ambiguous and a binding-time error occurs.

此外,在§7.5.3.2 Better function member下:

Optional parameters with no corresponding arguments are removed from the parameter list

这意味着当您在方法调用中省略最后两个参数并且推断出 NonGeneric 类型时(阅读 §7.5.2 中的类型推断),这两个方法看起来像这样:

Ext1(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext)

因此,它们将是模棱两可的...

我建议阅读规范的 §7.5.3.2 甚至整个 §7.5.3 以获取更多信息。

解决方案是更改您的方法声明或完全删除第一个重载并让第二个重载完成工作:)

关于c# - 默认参数和泛型的方法解析问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13359442/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com