Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么使用库A的C#客户机需要为库B(A使用的)提供一个using语句_C#_.net_Interface - Fatal编程技术网

为什么使用库A的C#客户机需要为库B(A使用的)提供一个using语句

为什么使用库A的C#客户机需要为库B(A使用的)提供一个using语句,c#,.net,interface,C#,.net,Interface,我有: 主程序类-使用库A 库A-具有与库B中的方法混合的部分类 库B-混合方法和接口 因此,在库B中,当我包含一个实现INode(在库B中定义)的部分节点类时,我突然在我的主类中得到一个错误,它使用库a中的节点。该错误告诉我,在主类中,我必须对库B使用using语句 有什么想法吗 编辑-除代码外 // *** PROGRAM *** class Program { static void Main(string[] args) {

我有:

  • 主程序类-使用库A
  • 库A-具有与库B中的方法混合的部分类
  • 库B-混合方法和接口
因此,在库B中,当我包含一个实现INode(在库B中定义)的部分节点类时,我突然在我的主类中得到一个错误,它使用库a中的节点。该错误告诉我,在主类中,我必须对库B使用using语句

有什么想法吗

编辑-除代码外

    // *** PROGRAM ***
    class Program
    {
        static void Main(string[] args)
        {
            var context = new Model1Container();
            Node myNode;  // ** WITHOUT A using for Library B I have an error here ***
         }
     }


// ** 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
    }
/***程序***
班级计划
{
静态void Main(字符串[]参数)
{
var context=new Model1Container();
Node myNode;//**没有使用库B我这里有一个错误***
}
}
//**图书馆A
名称空间拓扑
{
公共部分类节点
{
//从EF自动生成
}
公共分部类节点:INode//从库B添加扩展方法
{
公钥
}
}
//**图书馆B
命名空间ToplogyLibrary
{
公共静态类NodeExtns
{
nodeMixin(此INode节点)中的公共静态无效{
//XXXX
}
}
公共接口节点
{
//性质
T键{get;}
//方法
}
}

编辑2-澄清是引用还是使用错误:

因此,“Node myNode;”行出现的错误是:

类型错误1 'Topology.INode'1'是在中定义的 未被引用的程序集。 必须添加对程序集的引用 '拓扑,版本=1.0.0.0, 文化=中立, PublicKeyToken=null'。U:\My Dropbox\source\ToplogyLibrary\TopologyDAL\u ConsoleTest\Program.cs 11 13 TopologyDAL\u ConsoleTest

当我让VS为我修复它时,它会添加Library2作为参考。也就是说,在客户机代码之前或之后都没有“使用”。因此,问题是一个参考,而不是使用问题


编辑3-不是特别关于这个问题,但是我现在注意到在程序项目中,我不能看到mixin方法(从库B),除非我有一个对库B的using语句?我可能会就此提出一个单独的问题。

如果LibraryA公开属性、从方法返回对象或获取LibraryB中定义的类型的参数,并且您在主程序中声明或使用其中一种类型的变量,您需要using语句。

c#中的分部类只是存在于多个文件中的一个类。不能有两个文件在不同的名称空间中定义分部类。

由于库a使用库B中的混合方法和接口,如果库a和库B存在于不同的名称空间中,则需要using语句,这正是C的工作方式。编译器需要知道在哪里可以找到库A中使用的库B类型。

我的理解是,您只从主程序引用库A,而编译器告诉您添加对库B的引用,因为库A公开的某些类型是在库B中定义的

若要修复此问题,请在主程序项目中添加对库B的引用

这是一个小图表。如果库A公开库B中定义的类型,则Main也必须引用库B。以下情况不起作用:

_____________             _____________               _____________
| Main       |references  | Library A  |references    | Library B  |
|           -|------------|->         -|--------------|->          |
|            |            | public     |              | SomeType   |
|            |            |  SomeType  |              |            |
|            |            |            |              |            |
-------------             -------------               -------------
只有当库B中定义的类型可通过库a访问时,这才是一个问题。这将发生在以下情况之一:

  • 编辑的库A中定义的类型(
    节点
    )派生自库B中的类型(
    INode
  • 库A中定义的方法使用库B中的类型作为返回类型或参数
  • 库A中定义的类型将库B中的类型公开为属性或公共字段
您需要从Assembly1添加对Assembly3的引用以使其可编译

_____________             _____________               _____________
| Main       |references  | Library A  |references    | Library B  |
|           -|------------|->         -|--------------|->          |
|            |            | public     |              | SomeType   |
|            |references  |  SomeType  |              |            |
|           -|------------|------------|--------------|->          |
|            |            |            |              |            |
-------------             -------------               -------------

您所使用的是库A中的
节点
类,这是正确的。但是,
节点
类的部分定义是它实现了库B中的
INode
接口


节点
类存在的事实要求您包含对库B的引用。

正如其他答案正确解释的那样,您的主程序需要对库B的引用,因为库a通过其自己的公共API公开了库B类型。也就是说,
节点
公开实现了
索引节点
,使得该类型对主程序可见

通常,正确的解决方案只是将库B的引用添加到主程序中。毕竟,主程序在运行时肯定需要库B,即使它本身不直接访问该库中声明的任何类型

但是,如果出于某种原因添加引用有问题,有一种替代方法,假设您至少可以更改库A。也就是说,封装库B中类型的使用,以便使用库A的代码看不到它们。通常,这种封装将涉及某种代理或包装,隐藏第三个库的使用,以及(在某些情况下)向引用第二个库的部件公开第三个库的特征

例如,您可以将库A更改为如下所示:

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

    public partial class Node
    {
        public int Key { ... }

        private class NodeProxy : INode<int>
        {
            private readonly Node _node;

            public NodeProxy(Node node)
            {
                _node = node;
            }

            public int Key { get { return _node.Key; } }
        }

        private readonly NodeProxy _nodeProxy;

        public Node()
        {
            _nodeProxy = new NodeProxy(this);
        }
    }
}
请注意,该方法本身不添加库B的公共用法。相反,它使用(前面解释的)代理实例将调用委托给库B中声明的扩展方法。这样,实际上只有库A需要对库B进行引用;主程序可以引用库A而不暴露于库B中的任何类型,因此不需要显式引用


话虽如此,我要重申,事实上,不围绕这个问题工作是有价值的。首先,添加代理可以
public void FromNodeMixin()
{
    _nodeProxy.FromNodeMixin();
}