繁体   English   中英

在单独的程序集中使用受约束的通用扩展方法会产生参考错误

[英]Using constrained generic extension methods in a separate assembly gives a reference error

我创建了一个单独的程序集以包含常见的扩展方法,该扩展方法使用System.Web.dll (和其他)中的类。

然后,当我创建一个引用包含扩展方法的Utilities.dll集的新项目(控制台应用程序)时,如果它不使用扩展方法,则不需要在新项目中添加对System.Web.dll的引用。扩展了System.Web.dll程序集中的任何类(例如System.Web.UI.Control )。

当一种扩展方法将是通用方法时,一切将继续按预期工作。 但是,一旦我在将通用方法约束到System.Web.dll程序集中的类的方法中添加了约束,编译器就会抱怨我的新项目(控制台应用程序)需要引用System.Web.dll即使新项目仍未在该程序集中使用任何内容。

换句话说,只要我对通用方法没有约束,一切都会编译,但是一旦添加约束,编译器就会抱怨。

我的扩展方法的示例进行了汇编(编译为库Utilities.dll ):

 public static class StringExtensions { public static bool IsNullOrEmpty(this string value) { return string.IsNullOrEmpty(value); } } public static class ControlExtensions { // If I remove the where clause it compiles public static T FildChild<T>(this Control parent, string id) where T : Control { throw new NotImplementedException(); } } And here is a new console application that won't compile (unless I also add a reference to System.Web.dll ):  static void Main(string[] args) { bool isEmpty = "Hello World!".IsNullOrEmpty(); Console.ReadLine(); } Update: As Marc pointed out (below) puting the offending method in a separate namespace fixes the problem. 

public static class StringExtensions { public static bool IsNullOrEmpty(this string value) { return string.IsNullOrEmpty(value); } } public static class ControlExtensions { // If I remove the where clause it compiles public static T FildChild<T>(this Control parent, string id) where T : Control { throw new NotImplementedException(); } } And here is a new console application that won't compile (unless I also add a reference to System.Web.dll ): static void Main(string[] args) { bool isEmpty = "Hello World!".IsNullOrEmpty(); Console.ReadLine(); } Update: As Marc pointed out (below) puting the offending method in a separate namespace fixes the problem.

 public static class StringExtensions { public static bool IsNullOrEmpty(this string value) { return string.IsNullOrEmpty(value); } } public static class ControlExtensions { // If I remove the where clause it compiles public static T FildChild<T>(this Control parent, string id) where T : Control { throw new NotImplementedException(); } } And here is a new console application that won't compile (unless I also add a reference to System.Web.dll ):  static void Main(string[] args) { bool isEmpty = "Hello World!".IsNullOrEmpty(); Console.ReadLine(); } Update: As Marc pointed out (below) puting the offending method in a separate namespace fixes the problem. 


public static class StringExtensions { public static bool IsNullOrEmpty(this string value) { return string.IsNullOrEmpty(value); } } public static class ControlExtensions { // If I remove the where clause it compiles public static T FildChild<T>(this Control parent, string id) where T : Control { throw new NotImplementedException(); } } And here is a new console application that won't compile (unless I also add a reference to System.Web.dll ): static void Main(string[] args) { bool isEmpty = "Hello World!".IsNullOrEmpty(); Console.ReadLine(); } Update: As Marc pointed out (below) puting the offending method in a separate namespace fixes the problem.

But the question still remains why is the constraint a problem while the type Control was already used as a parameter to the method. and why is the namespace the solution when I already use the using But the question still remains why is the constraint a problem while the type Control was already used as a parameter to the method. and why is the namespace the solution when I already use the using在顶部But the question still remains why is the constraint a problem while the type Control was already used as a parameter to the method. and why is the namespace the solution when I already use the using指令But the question still remains why is the constraint a problem while the type Control was already used as a parameter to the method. and why is the namespace the solution when I already use the using

嗯,是! 为了进行编译,它需要能够解析公共/受保护的API中的所有内容。 否则它将无法强制执行约束。 我想它需要识别类型以查看扩展方法是否是方法的候选方法。

您可以尝试将扩展方法放置在其中带有“ Web”的子命名空间中-至少这样,它将不会溢出到常规代码中。 我已经检查了 ,这可以解决问题。 优良作法是将扩展方法的命名空间分开,以允许调用方控制它们何时应在范围内。

为了执行,还需要能够在内部而不是使用API暴露解决任何问题。 这是标准行为。

@Marc为您提供了原因。 我建议,作为一种好的做法,除了Com.Company.Extensions外,还应将引用Web类的所有内容分解为另一个程序集,例如Com.Company.Extensions.Web。 然后,您既可以将其包含在Web项目中,也可以仅将非Web扩展名包含在其他项目中。

暂无
暂无

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

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