两个具有相同名称的扩展方法

时间:2014-12-31 18:07:38

标签: c# extension-methods

我有以下两种扩展方法(方法的主体对我的问题不是特别重要,但无论如何包括代码)

public static class DictionaryExtensions
{
    public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key, TValue defaultValue)
    {
        return (source.ContainsKey(key) ? source[key] : defaultValue);
    }
}

public static class WebExtensions
{
    public static T GetValue<T>(this HttpContext context, string name, T defaultValue)
    {
        object value = context.Request.Form[name] ?? context.Request.QueryString[name];
        if (value == null) return defaultValue;
        return (T)value;
    }
}

这两个方法共享相同的名称,但它们扩展了两种非常不同的类型。我希望以下代码简单,编译器能够选择适当的扩展方法:

var myDict = new Dictionary<int, string>()
{
    { 1, "foo" },
    { 2, "bar" }
};
var result = myDict.GetValue(5, "baz");

但是,由于某些未知原因,Visual Studio拒绝使用以下编译时错误编译我的代码:“类型'System.Web.HttpContext'在未引用的程序集中定义。您必须添加引用装配'System.Web'“。此错误告诉我编译器在WebExtensions类中选择了GetValue扩展方法,而不是在DictionaryExtension类中选择了。

我能够解决以下问题:

var result = DictionaryExtensions.GetValue(myDict, 5, "baz");

但是我试图理解为什么编译器首先被混淆了。有人知道为什么吗?

2 个答案:

答案 0 :(得分:5)

另一种选择是将2个Extension类分解为单独的名称空间,不要添加using类,其中WebExtensions类位于您的使用代码中。这样编译器就不会尝试将GetValue解析为WebExtensions

答案 1 :(得分:3)

只需执行编译器所说的内容并添加对System.Web.dll的引用。然后它应该编译。

存在这些扩展方法类的外部程序集依赖于System.Web.dll。编译器应该能够找出重载,但为了做到这一点,它需要引用HttpContext存在的程序集,它位于System.Web.dll中。

另一方面,如果您不希望使用扩展方法程序集的项目依赖于System.Web.dll,则需要在单独的程序集中定义这2个扩展方法类。

@Steve Danner has a good solution too:将两个扩展方法类放在同一个程序集中的不同名称空间中,并省略包含WebExtensions类的名称空间的using语句。

我偶尔会遇到类似System.Runtime.Serialization,System.ServiceModel.Activation等问题。当你有一个两次删除的依赖项时,可能会发生这种情况。换句话说,你的根项目取决于一个程序集,它取决于另一个第三个程序集的类型。