混合泛型方法和扩展方法方法

2023-09-03 16:43:38 作者:被撕碎了的回忆

我创建了 Class1.GetChild< T>()其中T:DependencyObject的中的 lib1.dll 的组件扩展方法。在此之后,所有的组件依赖于的 lib1.dll 的没有编译错误:

I created the Class1.GetChild<T>() where T : DependencyObject extension method in lib1.dll assembly. After that, all assemblies that depends on lib1.dll failed to compile with error:

类型System.Windows.DependencyObject'是一个assemeb​​ly定义   未引用。您必须添加一个引用组件   WindowsBase等等...

The type 'System.Windows.DependencyObject' is defined in an assemebly that is not referenced. You must add a reference to assembly 'WindowsBase' etc...

为什么要依赖程序需要的 WindowsBase 的,即使他们不使用 GetChild

Why dependent assemblies requires WindowsBase even if they don't use GetChild?

要重现(VS2010 .NET4):

To reproduce (vs2010 .net4):

lib1.dll (引用的 WindowsBase 的)

namespace lib1
{
    public static class Class1
    {
        public static T GetChild<T>(this DependencyObject src) where T : DependencyObject
        {
            return default(T);
        }
    }

    public static class Class2
    {
        public static int SomeExtMethod(this string src)
        {
            return 0;
        }
    }
}

lib2.dll (引用的 LIB1 的而不是 WindowsBase 的)

lib2.dll (references lib1 but not WindowsBase)

using lib1;
class someClass
{
    void someFct()
    {
        "foo".SomeExtMethod(); // error: The type 'System.Windows.DependencyObject'
                // is defined in an assemebly that is not referenced. 
                // You must add a reference to assembly 'WindowsBase' etc..
    }
}

更新:的

Update:

我觉得有混合泛型方法和扩展方法时的definitly东西。我所要证明的问题,下面的示例所示:

I think there's definitly something when mixing generic methods and extension methods. I tried to demonstrate the issue in the following sample:

// lib0.dll
namespace lib0
{
    public class Class0 { }
}

// lib1.dll
using lib0;
namespace lib1
{
    public static class Class1
    {
        public static void methodA<T>() where T : Class0 { }    // A
        public static void methodB(Class0 e) { }                // B
        public static void methodC(this int src) { }            // C
    }

    public static class Class2
    {
        public static void methodD(this String s) { }
    }
}

// lib2.dll
using lib1;
class someClass
{
    void someFct()
    {
        Class2.methodD("");  // always compile successfully
        "".methodD();        // raise the 'must add reference to lib0' error depending on config. see details below.
    }
}

A,// B,// C - >编译确定

A, //B, //C -> compile ok

A,B,// C - >编译确定

// A,B,C - >编译确定

A,// B,C - >引发错误

A,B,C - >引发错误

// A 办法的methodA 的评论。正如达指出,类型推断可能发挥一定的作用。还是好奇,想知道来龙去脉。

//A means methodA is commented. As Damien pointed out, type inference might play some role. Still curious to know the ins and outs.

推荐答案

您的情况已经回答了微软在这里: https://connect.microsoft.com/VisualStudio/feedback/details/668498/problem-with-extension-method-in-c-compiler

Your situation has been answered by Microsoft here: https://connect.microsoft.com/VisualStudio/feedback/details/668498/problem-with-extension-method-in-c-compiler

有其他的使用情况,以及独立于该错误产生这个错误的扩展方法。

There are other use-cases as well independent of extension methods which produce this error wrongly.

考虑一下:

定义的类型泛型方法,说TP1,在库中定义说LB1。 类型限制在一些其他图书馆LB2定义某种类型的泛型方法。 在TP1定义的另一种方法。 现在,在您的图书馆参考之用LB1,并尝试呼叫类型TP1 的第二个方法 Define a generic method in a type, say TP1, defined in library say LB1. Type constrain the generic method on some type defined in some other library LB2. Define another method in TP1. Now in your library reference only LB1 and try to call the second method of type TP1

如果你不使用TP1但在LB1定义了一些其他类型的,你没有得到的错误。 此外,即使一类TP1的方法,预计LB2定义的类型的参数(并且不调用此方法),也不会产生这种错误

If you don't use TP1 but some other type defined in LB1, you do not get the error. Also, even if one of the method of type TP1 expects a parameter of the type defined in LB2 (and you do not call this method) it does not produce this error