簡體   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