代码之家  ›  专栏  ›  技术社区  ›  Yona

在单独的部件中使用受约束的常规扩展方法会产生引用错误

  •  5
  • Yona  · 技术社区  · 17 年前

    我创建了一个单独的程序集来包含公共扩展方法,扩展方法使用 System.Web.dll (和其他)。

    当我创建一个引用 Utilities.dll 包含扩展方法的程序集,我不需要添加对的引用 如果新项目不使用扩展中任何类的扩展方法,则添加到新项目 System.Web.dll 装配(例如 System.Web.UI.Control

    当其中一个扩展方法是泛型方法时,一切都会按预期继续工作。但只要我向泛型方法添加约束,将其约束到 汇编编译器会抱怨我的新项目(控制台应用程序)需要引用 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();
        }
    }
    

    这是一个新的控制台应用程序,它不会编译(除非我还添加了对 System.Web.dll

        static void Main(string[] args)
        {
            bool isEmpty = "Hello World!".IsNullOrEmpty();
    
            Console.ReadLine();
        }
    


    正如Marc(下面)指出的,将有问题的方法放在一个单独的名称空间中可以解决这个问题。

    但是问题仍然存在,为什么当类型控件已经用作方法的参数时,约束是一个问题。当我已经在顶部使用using指令时,为什么名称空间是解决方案呢。

    2 回复  |  直到 17 年前
        1
  •  5
  •   Marc Gravell    17 年前

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

    您可以尝试将扩展方法放置在包含“Web”的子命名空间中,至少这样它不会溢出到常规代码中。 我查过了 ,这就解决了问题。分离扩展方法的名称空间是一种很好的做法,以允许调用方控制它们何时应该在范围内。

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

        2
  •  1
  •   tvanfosson    17 年前

    @马克告诉你为什么。我建议,作为一种良好的实践,您可以将任何引用web类的内容分解到另一个程序集中,例如Com.Company.Extensions.web,以及Com.Company.Extensions。然后,您可以在web项目中同时包含这两个扩展,并且在其他项目中仅包含非web扩展。

    推荐文章