两个同名的扩展方法
本文关键字:扩展 方法 两个 | 更新日期: 2023-09-27 18:35:43
我有以下两个扩展方法(方法的主体对于我的问题不是特别重要,但无论如何都包括代码)
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 个扩展类分解为单独的命名空间,并且不要在 WebExtensions
类驻留在使用代码中的位置添加 using
语句。 这样编译器就不会尝试将GetValue
解析为WebExtensions
。
只需按照编译器所说的操作并添加对 System.Web.dll 的引用。然后它应该编译。
存在这些扩展方法类的外部程序集依赖于 System.Web.dll。编译器应该能够找出重载,但为了做到这一点,它需要引用HttpContext
存在的程序集,即 System.Web.dll。
另一方面,如果您不希望使用扩展方法程序集的项目依赖于 System.Web.dll,则需要在单独的程序集中定义这两个扩展方法类。
@Steve Danner 也有一个很好的解决方案:将两个扩展方法类放入同一程序集中的不同命名空间中,并省略包含 WebExtensions
类的命名空间的 using 语句。
我偶尔会遇到诸如System.Runtime.Serialization,System.ServiceModel.Activation等内容。当您的依赖项被删除两次时,可能会发生这种情况。换句话说,根项目依赖于一个程序集,该程序集依赖于另一个程序集的类型。