用String.Format扩展方法奇怪的编译错误

时间:2012-10-23 16:59:39

标签: c# string extension-methods string-formatting

  

可能重复:
  Is it possible to create an extension method to format a string?

我有这堂课:

public class Person 
{
    public string Name { get; set; }
    public uint Age { get; set; }

    public override string ToString()
    {
        return String.Format("({0}, {1})", Name, Age);
    }
}

扩展方法:

public static string Format(this string source, params object[] args)
{
    return String.Format(source, args);
}

我想测试它,但我有以下奇怪的行为:

Person p = new Person() { Name = "Mary", Age = 24 };

// The following works
Console.WriteLine("Person: {0}".Format(p));
Console.WriteLine("Age: {0}".Format(p.Age));

// But this gives me a compiler error:
Console.WriteLine("Name: {0}".Format(p.Name));

编译错误:

无法使用对实例的引用访问成员'string.Format(string,params object [])'。使用类型名称对其进行限定。

为什么呢?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

您创建了一个与现有方法(String.Format)具有相同签名的扩展方法。您需要为扩展方法使用其他名称。像FormatWith(...)之类的东西。

我的立场得到了纠正。我只是组合一个单元测试来验证这种行为,并且无法调用“some string”.Format(...)。在C#中,编译器为我提供了“无法在非静态上下文中访问静态方法'格式'”。鉴于此,我猜你已经设法混淆了编译器。

答案 1 :(得分:1)

由于p.Name是一个字符串,因此在第三种情况下您的调用不明确:

string.Format(string)

VS

{string instance}.Format(object[]);

解析器选择的方法最适合签名(在您的情况下为stringobject[]),而不是扩展方法。

您可以通过重命名扩展方法或将第二个参数强制转换为对象来解决问题,以防止解析器选择静态方法:

Console.WriteLine("Name: {0}".Format((object)p.Name));