3

可能重复:
是否可以创建扩展方法来格式化字符串?

我有这堂课:

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 [])”。使用类型名称对其进行限定。

为什么?我怎么解决这个问题?

4

2 回答 2

1

因为p.Name是一个字符串,所以在第三种情况下你有一个模棱两可的调用:

string.Format(string)

对比

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

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

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

Console.WriteLine("Name: {0}".Format((object)p.Name));
于 2012-10-23T17:22:49.877 回答
1

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

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

于 2012-10-23T17:03:17.807 回答