混合泛型方法和扩展方法我在Class1.GetChild()whereT:DependencyObject中创建了Class1.GetChild()whereT:DependencyObject扩展方法。之后,所有依赖于lib1.dll的程序集都无法编译并出现错误:“System.Windows.DependencyObject”类型在未引用的Configurable中定义。您必须添加对程序集“WindowsBase”等的引用...为什么依赖程序集需要WindowsBase,即使它们不使用GetChild?.重现(vs2010.net4):lib1.dll(引用WindowsBase)namespacelib1{publicstaticclassClass1{publicstaticTGetChild(thisDependencyObjectsrc)whereT:DependencyObject{returndefault(T);}}publicstaticclassClass2{publicstaticintSomeExtMethod(thisstringsrc){return0;}}}lib2.dll(引用lib1但不引用WindowsBase)使用lib1;classsomeClass{voidsomeFct(){“foo”.SomeExtMethod();//错误:“System.Windows.DependencyObject”类型//在未引用的程序集中定义。//您必须添加对程序集“WindowsBase”等的引用。}}。更新:我认为混合通用方法和扩展方法时一定有一些东西。我尝试在以下示例中演示该问题://lib0.dllnamespacelib0{publicclassClass0{}}//lib1.dllusinglib0;namespacelib1{publicstaticclassClass1{publicstaticvoidmethodA()whereT:Class0{}//ApublicstaticvoidmethodB(Class0e){}//BpublicstaticvoidmethodC(thisintsrc){}//C}publicstaticclassClass2{publicstaticvoidmethodD(thisStrings){}}}//lib2.dll使用lib1;classsomeClass{voidsomeFct(){Class2.methodD("");//总是编译成功"".methodD();//根据配置引发“必须添加对lib0的引用”错误。请参阅下面的详细信息。}}A,//B,//C->编译成功A,B,//C->编译成功//A,B,C->编译成功A,//B,C->抛出错误A,B,C->引发错误//A意味着方法//A被注释。正如Damien指出的那样,类型推断可能会发挥作用。仍然很想知道这件事的来龙??去脉。Microsoft已在此处回答了您的案例:https://connect.microsoft.com/VisualStudio/feedback/details/668498/problem-with-extension-method-in-c-compiler还有其他用例也与扩展方法无关,这个错误是错误产生的。考虑一下:在类型中定义的泛型方法,比如TP1,在库中定义为LB1。在某些其他库LB2中定义的某些类型上的类型约束泛型方法。在TP1中定义另一个方法。现在你的库中只引用了LB1,尝试调用TP1类型的第二种方法如果你不使用TP1,而是在LB1中定义其他类型,就不会报错了。此外,即使其中一个TP1类型的方法需要LB2中定义的类型的参数(并且您不调用此方法),当一个程序集依赖于另一个程序集时也不会产生此错误,第一个程序集也依赖于另一个程序集的所有依赖项——无论使用什么。程序集依赖关系被有效解耦,编译后可以部署任一程序集的另一个版本,编译器无法知道在这种情况下,第二个程序集中的一个或多个依赖项将不被第一个程序集使用。要解决此问题,您只需添加对WindowsBase的引用。或者,正如prashanth指出的那样,将SomeExtMethod放入另一个程序SomeExtMethod中,这样使用它的代码就不需要依赖于WindowsBase。更新:如果您不使用程序集中的任何内容,则不需要任何依赖项。但是,无论何时使用程序集,都需要该程序集的所有依赖项。这在VisualStudio添加引用的方式中很明显。如果您添加对程序集的引用,它会将所有相关程序集(未在GAC中注册)与您添加的程序集一起复制到debug/release目录中。更新:关于编译错误:就是这样写的——可能没有其他原因。如果未引用依赖程序集,是否会出现编译错误是个好主意?也许,您可以使用参考中的内容,也可以直接使用参考中的内容——编译错误比部署错误更好。为什么不在每个未引用的辅助依赖项上都出现编译错误?又是这样写的。也许这里的错误也很好;但这将是一个突破性的变化,需要一个非常有说服力的理由。我不确定除了编译器团队中的某个人以外的任何人都可以回答这个问题。我现在认为它与类型推断有关-但§7.6.5.1方法调用讨论了推断,而§7.6.5.2扩展方法调用对此事保持沉默-尽管在搜索时显然确实发生了推断适用的扩展方法确实发生.我认为它在对标识符进行比较之前会尝试某种形式的推理(这将完全排除扩展方法,因为它是错误的名称)。显然,如果它不能理解类型约束,就不能对类型执行任何形式的推断。因此,当您将类型约束更改为仅类时,它现在成功地传递了这个方法——它可以推断出类型参数,但它现在成功地取消了这个扩展方法。当您引用另一个程序集时,我假设编译器需要能够解析该程序集中定义的任何方法签名,因此它知道在看到对它的调用时去哪里找到该函数。如果使用。将GetChild()函数替换为publicstaticTGetChild(thisTsrc){if(typeof(T)==typeof(DependencyObject))returndefault(T);否则返回默认值(T);}或类似的东西,它不需要您包含对正在运行的WindowsBase的引用。但如果您将whereT:DependencyObject添加到签名中,它确实需要它。事实上,您可以在项目中使用任何您想要的程序集引用,只要您不以任何方式公开它们即可。一旦公开它们,使用您的库的每个其他项目都需要能够处理它们,因此需要引用本身。也许ILMerge会解决这个问题。这个想法是您创建2个dll并将它们合并为一个。这样你就可以拥有一个dll但引用它两次。然后,您可以将GUI代码与其余代码分开,只添加对您需要的特定项目的引用。答案很简单。这是因为该方法非常公开。这意味着它对lib2.dll可见(在您的情况下)。换句话说,您可以调用此方法。它还有一个约束,即只有从DependencyObject继承的类才能调用此方法。这就是您需要引用“WindowsBase”的原因。以上就是C#学习教程分享的全部内容:混合泛型方法和扩展方法。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处:
