我有:
所以在库B中,当我包含一个实现INode的部分Node类(在库B中定义)时,我突然在我的主类中出现错误,它使用来自库A的Node。错误告诉我在Main Class中我有对库B有一个使用声明。
有什么想法吗?
编辑 - 代码
除外 // *** 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
}
}
编辑2 - 澄清它是引用还是使用错误:
所以针对“Node myNode”出现的错误;行是:
错误1类型 'Topology.INode`1'在中定义 未引用的程序集。 您必须添加对程序集的引用 '拓扑,版本= 1.0.0.0, 文化=中性, 公钥=空”。 U:\我的 Dropbox \ source \ ToplogyLibrary \ TopologyDAL_ConsoleTest \ Program.cs 11 13 TopologyDAL_ConsoleTest
当我让VS为我修复它时,它添加了Library2作为参考。也就是说,在客户端代码之前或之后没有“使用”。所以问题是参考不使用问题。
编辑3 - 不是特别关于这个问题,但我现在注意到在程序项目中,我看不到mixin方法(来自库B),除非我有一个使用语句到库B?我可能会创建一个单独的问题。
答案 0 :(得分:5)
如果LibraryA公开属性,从方法返回对象,或者获取LibraryB中定义的类型的参数,并且在其中一种类型的主程序中声明或使用变量,则需要使用using语句。
答案 1 :(得分:5)
我对正在发生的事情的理解是,您只从主程序中引用库A,编译器会告诉您添加对库B的引用,因为库A中公开的某些类型是在库B中定义的。
要解决此问题,请将库B的引用添加到主程序项目中。
这是一个小图。如果库A公开了库B中定义的类型,那么Main也必须引用库B.以下情况不起作用:
_____________ _____________ _____________
| Main |references | Library A |references | Library B |
| -|------------|-> -|--------------|-> |
| | | public | | SomeType |
| | | SomeType | | |
| | | | | |
------------- ------------- -------------
当图书馆B中定义的类型可以通过库A访问时,这只是一个问题。这将是以下情况之一:
Node
)派生自库B中的类型(INode<int>
)。您需要从Assembly1添加对Assembly3的引用以使其编译。
_____________ _____________ _____________
| Main |references | Library A |references | Library B |
| -|------------|-> -|--------------|-> |
| | | public | | SomeType |
| |references | SomeType | | |
| -|------------|------------|--------------|-> |
| | | | | |
------------- ------------- -------------
答案 2 :(得分:1)
由于库A在库B中使用混合方法和接口,如果库A和库B存在于不同的命名空间中,则需要使用using语句,这就是C#的工作原理。编译器需要知道在哪里可以找到库A中使用的库B类型。
答案 3 :(得分:0)
您正在使用的是图书馆A中的Node
课程,这是真的。但是,Node
类的部分定义是它实现了库B中的INode<int>
接口。
Node
类存在的事实要求您包含对库B的引用。
答案 4 :(得分:0)
正如其他答案已正确解释,您的主程序需要引用库B,因为库A已通过其自己的公共API公开了库B类型。即Node
公开实施INode<T>
,导致该类型对主程序可见。
通常,正确的解决方案是将库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中的扩展程序,只需使用_nodeProxy
成员而不是this
。
当然,上面假设主程序实际上没有直接使用库B中的任何内容,并且库B中所有类型的用法都只在库A中找到,甚至没有在库A中以返回值显示,财产类型等。但是,如果不是这样呢?例如,如果您希望主程序能够从库B中访问扩展方法而不引用该库,该怎么办?
好吧,我的第一个答案是&#34;请继续参考大会!&#34; :)但是为了争论,让我们说你出于某种原因无法做到这一点,或者至少这样做非常不方便。然后,您可以扩展代理方法,以将代理方法添加到库A类型,然后再将类型委托给库B中的实现。
扩展上面的例子,可以在Node
类声明中添加另一种方法:
public void FromNodeMixin()
{
_nodeProxy.FromNodeMixin();
}
请注意,该方法本身不会添加库B的公共用法。相反,它使用(先前解释的)代理实例将调用委托给库B中声明的扩展方法。这样,只有库A实际需要参考图书馆B;主程序可以引用库A而不会暴露给库B中的任何类型,因此不需要显式引用。
现在说了这些,我将重申 实际上在而不是处理该问题的价值。首先,添加代理可能非常耗时。它只适用于一两种类型,可能有一些方法。但是,如果你试图隐藏每一个间接使用DLL的方法,那么它将真正快速实现,否则你将使用大量的功能。
正如我之前提到的,当然不必添加对库B的引用并不意味着库B不需要存在来运行程序。您仍然需要在那里拥有库,以便在库A调用它时,可以使用它。拥有主程序参考库B是我所知道的最简单的方法之一,以确保将库B复制到构建输出目录以确保DLL在那里。
答案 5 :(得分:-1)
c#中的部分类只是存在于多个文件中的一个类。您不能有2个文件在不同的命名空间中定义部分类。