如果库 B 的 extn 方法在库 A ' 中使用,为什么我需要对库 B 的 extn 方法使用 using 语句?它是我的客户使用的库 A?

发布于 2024-09-02 04:57:14 字数 1194 浏览 6 评论 0原文

我有:

  • 主程序类 - 使用库 A
  • 库 A - 具有混合库 B 的方法的部分类
  • 库 B - 混合方法和方法接口

为什么我需要 LibaryB 的 using 语句才能让它们的扩展方法在主类中工作?假设库 B 定义了将要扩展的类。

编辑 - 除了代码

    // *** PROGRAM ***
    using TopologyDAL;
    using Topology;  // *** THIS WAS NEEDED TO GET EXTN METHODS APPEARING ***
    class Program
    {
        static void Main(string[] args)
        {
            var context = new Model1Container();
            Node myNode;  // ** trying to get myNode mixin methods to appear seems to need using line to point to Library B ***
         }
     }


// ** LIBRARY A
namespace TopologyDAL
{
    public partial class Node
    {
        // Auto generated from EF
    }

    public partial class Node : INode<int>   // to add extension methods from Library B
    {
        public int Key
    }
}

// ** LIBRARY B
namespace ToplogyLibrary
{
    public static class NodeExtns
    {
        public static void FromNodeMixin<T>(this INode<T> node) {
           // XXXX
        }
    }
    public interface INode<T> 
    {
        // Properties
        T Key { get; }

        // Methods
    }

}

I have:

  • Main Program Class - uses Library A
  • Library A - has partial classes which mix in methods from Library B
  • Library B - mix in methods & interfaces

Why would I need a using statement to LibaryB just to get their extension methods working in the main class? That is given that it's Library B that defines the classes that will be extended.

EDIT - Except from code

    // *** PROGRAM ***
    using TopologyDAL;
    using Topology;  // *** THIS WAS NEEDED TO GET EXTN METHODS APPEARING ***
    class Program
    {
        static void Main(string[] args)
        {
            var context = new Model1Container();
            Node myNode;  // ** trying to get myNode mixin methods to appear seems to need using line to point to Library B ***
         }
     }


// ** LIBRARY A
namespace TopologyDAL
{
    public partial class Node
    {
        // Auto generated from EF
    }

    public partial class Node : INode<int>   // to add extension methods from Library B
    {
        public int Key
    }
}

// ** LIBRARY B
namespace ToplogyLibrary
{
    public static class NodeExtns
    {
        public static void FromNodeMixin<T>(this INode<T> node) {
           // XXXX
        }
    }
    public interface INode<T> 
    {
        // Properties
        T Key { get; }

        // Methods
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷港 2024-09-09 04:57:14

仅当您导入定义扩展方法的命名空间时,扩展方法才可用。

否则,编译器将需要解析每个引用库中的每个扩展方法,这会减慢编译时间。
此外,如果不同的命名空间包含具有相同签名的扩展方法,则将无法使用扩展方法。

总之,扩展方法本身就是一种功能,需要导入其名称空间;它们不会使用它们扩展的类的名称空间自动导入。

Extension methods are only available if you import the namespace that they are defined in.

Otherwise, the compiler would need to resolve against every single extension method in every single referenced library, which would slow down the compile time.
Also, that would make it impossible to use an extension method if a different namespace contains an extension method with the same signature.

In summary, extension methods are features in their own right and require their namespace to be imported; they are not automatically imported with the namespace of the class that they extend.

又怨 2024-09-09 04:57:14

这是扩展方法的一个不幸的可发现性问题。为了使它们可用,您需要为包含具有扩展的静态类的命名空间添加一个 using 语句。查看此博客,了解扩展方法。

以下是有关扩展方法的一些背景

那么编译器如何知道哪个
扩展方法来绑定?编译器
寻找扩展方法
当调用时最里面的命名空间
为扩展方法创建,然后在
导入的所有命名空间
“使用”条款。这个过程是
随后向外移动,直到我们到达
最顶层的命名空间。

由于扩展方法可以
导入到当前上下文中
“使用”条款并受任何约束
可分配的对象(参见
可兑换部分了解详细信息)
实例参数,各种
有趣的可能性
扩展由a实现的方法
类型。这可以简单地通过以下方式完成
导入扩展库
方法并使用这些方法就好像
它们是在您定义的类型上声明的
不拥有。这意味着

  1. 根据您导入的库,代码可以执行不同的操作
    事情。

  2. 客户可以通过一种有趣的方式来扩展他不拥有的类型。

我的理解是,使用扩展方法就像使用任何其他类型一样,只是您无法限定它们(这在语法上是不可能的),因此需要 using 语句。由于您可以在不同命名空间的不同类中定义多个它们,因此编译器需要一种方法来解决歧义。

我设想将来 Visual Studio 将添加一项功能,以便在您键入方法名称时导入正确的命名空间,这与类和接口名称的处理方式类似。

考虑这种情况:

namespace FruityNamespace {
  public static class FruityExtensions {
    public static string ToFunString(this int value) {return value + " bananas"; }
  }
}

namespace VegetablNamespace {
  public static class VegetablyExtensions {
    public static string ToFunString(this int value) {return value + " carrots"; }
  }
}

//In some other source file
static void Main(/**/) {
  int things = 3;
  3.ToFunString(); //error CS1061: 'System.Int' does not contain a definition for 'ToFunString' and no extension method 'ToFunString' accepting a first argument of type 'System.Int' could be found (are you missing a using directive or an assembly reference?)
}

为了使用任何这些扩展方法,您需要导入正确的命名空间:

using FruityNamespace;
//OR
using VegetablyNamespace;

您可能会问导入两个命名空间时会发生什么。你会得到一个编译器错误,就像这样:

错误 CS0121:以下方法或属性之间的调用不明确:“VegetablNamespace.VegeticallyExtensions.ToFunString(int)”和“FruityNamespace.FruityExtensions.ToFunString(int)”

This is an unfortunate discoverability issue with extension methods. In order to make them available you need to add a using statement for the namespace containing the static class that has the extensions. Check out this blog about extension methods.

Here is some background on extension methods:

So how is the compiler to know which
extension method to bind? The compiler
looks for extension methods in the
innermost namespace when the call is
made for extension methods and then in
all the namespaces imported by the
"using" clause. This process is
followed moving outward until we reach
the topmost namespace.

Since extension methods can be
imported in to the current context by
the "using" clause and bound to any
object which is assignable(see
convertibility section for details) to
the instance parameter, all sorts of
interesting possibilities open up for
extending the methods implemented by a
type. This can simply be done by
importing a library of extension
methods and using these methods as if
they were declared on a type that you
don't own. This means that

  1. Depending on the library you import the code can be made to do different
    things.

  2. The client gets an interesting way to extend a type that he does not own.

My understanding is that using extension methods is just like using any other type, except that you can't qualify them (that is just syntactically impossible), hence the need for using statement. Since you can define multiple of them in different classes in different namespaces, the compiler needs a way to resolve ambiguity.

I envisage that in future Visual Studio will add a feature to import the right namespace when you type in the method name, in a similar way it does so for class and interface names.

Consider this scenario:

namespace FruityNamespace {
  public static class FruityExtensions {
    public static string ToFunString(this int value) {return value + " bananas"; }
  }
}

namespace VegetablNamespace {
  public static class VegetablyExtensions {
    public static string ToFunString(this int value) {return value + " carrots"; }
  }
}

//In some other source file
static void Main(/**/) {
  int things = 3;
  3.ToFunString(); //error CS1061: 'System.Int' does not contain a definition for 'ToFunString' and no extension method 'ToFunString' accepting a first argument of type 'System.Int' could be found (are you missing a using directive or an assembly reference?)
}

In order to use any of those extension methods you need to import the right namespace:

using FruityNamespace;
//OR
using VegetablyNamespace;

You might ask what happens when you import both namespaces. You get a compiler error just like this:

error CS0121: The call is ambiguous between the following methods or properties: 'VegetablNamespace.VegetablyExtensions.ToFunString(int)' and 'FruityNamespace.FruityExtensions.ToFunString(int)'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文