简体   繁体   English

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

[英]Two extension methods with same name

I have the following two extension methods (the body of the methods is not particularly important for my question, but including the code anyway) 我有以下两种扩展方法(方法的主体对我的问题不是特别重要,但无论如何包括代码)

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;
    }
}

These two methods share the same name but they extend two very different types. 这两个方法共享相同的名称,但它们扩展了两种非常不同的类型。 I would expect the following code to be simple and the compiler to be able to pick the appropriate extension method: 我希望以下代码很简单,编译器能够选择适当的扩展方法:

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

However, for some unknown reason, Visual Studio refuses to compile my code with the following compile-time error: "The type 'System.Web.HttpContext' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web'" . 但是,由于某些未知原因,Visual Studio拒绝使用以下编译时错误编译我的代码:“类型'System.Web.HttpContext'在未引用的程序集中定义。您必须添加对程序集的引用' System.Web'“。 This error tells me that the compiler selected the GetValue extension method in the WebExtensions class instead of the one in the DictionaryExtension class. 此错误告诉我编译器选择了WebExtensions类中的GetValue扩展方法,而不是DictionaryExtension类中的GetValue扩展方法。

I was able to get around the problem with the following: 我能够解决以下问题:

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

but I'm trying to understand why the compiler was confused in the first place. 但我试图理解为什么编译器首先被混淆了。 Does anybody know why? 有人知道为什么吗?

Another option is to break your 2 Extension classes out into separate namespaces and do not add a using statement where the WebExtensions class resides in your consuming code. 另一种选择是将2个Extension类分解为单独的名称空间,并且不要using WebExtensions类的消费代码中添加using语句。 That way the compiler won't try and resolve GetValue to WebExtensions . 这样编译器就不会尝试将GetValue解析为WebExtensions

Just do what the compiler says and add a reference to System.Web.dll. 只需执行编译器所说的内容并添加对System.Web.dll的引用。 Then it should compile. 然后它应该编译。

Your external assembly where these extension method classes exist take a dependency on System.Web.dll. 存在这些扩展方法类的外部程序集依赖于System.Web.dll。 The compiler should be able to figure out the overload, but in order to do so, it needs to reference the assembly where HttpContext exists, which is in System.Web.dll. 编译器应该能够找出重载,但为了做到这一点,它需要引用HttpContext存在的程序集,它位于System.Web.dll中。

On the other hand if you don't want your project that consumes the extension method assembly to take a dependency on System.Web.dll, then you need to define those 2 extension method classes in separate assemblies. 另一方面,如果您不希望使用扩展方法程序集的项目依赖于System.Web.dll,则需要在单独的程序集中定义这2个扩展方法类。

@Steve Danner has a good solution too : put the two extension method classes into different namespaces in the same assembly, and omit the using statement for the namespace that contains the WebExtensions class. @Steve Danner也有一个很好的解决方案 :将两个扩展方法类放在同一个程序集中的不同命名空间中,并省略包含WebExtensions类的命名空间的using语句。

I run into this occasionally with things like System.Runtime.Serialization, System.ServiceModel.Activation, etc. It can happen when you have a dependency that is twice-removed. 我偶尔会遇到System.Runtime.Serialization,System.ServiceModel.Activation等问题。当你有一个两次删除的依赖项时,可能会发生这种情况。 In other words your root project depends on an assembly which depends on a type another third assembly. 换句话说,你的根项目取决于一个程序集,它取决于另一个第三个程序集的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM