如何在一个C#项目中使用另一个C#项目的类

156

在同一解决方案中,我有两个项目:P1和P2。如何在P2中使用P1的一个类?


这里有一个非常相似的问题链接 - RBT
11个回答

268
  1. 在“解决方案资源管理器”树中展开P2项目,右键单击(Shift+F10)“依赖项”节点,然后选择“添加项目引用...”。
  2. 在“添加引用”对话框中,选择您的P1项目。
  3. 如果您正在使用命名空间,则需要通过在P2文件中添加“using”语句来导入P1类型的命名空间。

请注意,您希望直接访问的P1中的类型必须具有足够的访问级别:通常意味着它们必须被设置为公共的。


注意:如果您正在处理旧项目(例如.NET Framework),则可能没有“依赖项”节点。在这种情况下,请右键单击项目,从菜单中选择“添加引用”,然后确保在左侧选择了“项目”选项卡。


非常好的建议,先生。我以前会粘贴链接,但每次更改文件路径时都必须更新它们。使用项目引用就轻松得多了。谢谢您! - IneedHelp
3
如果您在P1中已经有对P2的引用,那么上述操作将会创建一个“循环依赖”问题... - komodosp
5
是的,它可以。您需要将要共享的元素抽象出来并放入第三个项目中,您可以有创意地命名为P3,并使其他两个项目引用该项目。 - Paul Ruane
1
作为一名非.NET开发人员,我真的认为这应该是被接受的答案...谢谢Paul(x2)。 - thisIsTheFoxe
您可能需要重新启动Visual Studio才能使其正常工作。 - NoJoshua

69

只需要在P2中加入对P1的引用即可。


15
如果该类是非公共的,或者P2是P1的友元,则此方法不起作用。 - Manfred
7
在这种情况下,您有三个选项: 1)合并这两个项目。 2)将类设为 internal,并添加 P2 作为 "InternalsVisibleTo" 属性(更多信息请参见:http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx)。 3)如果以上两种方法都不可行 - 您必须使用反射来从 P2 实例化并调用类 P1。 - Nissim
45
我希望你能给我一份更详细的答复。这个回答几乎让人感觉像是在挖苦我。 - shteeven
11
举个例子会更好。 - Paul Alexander
3
此外,两个项目需要针对相同的.NET框架。请检查每个项目的属性,在“应用程序”选项卡上应该有一个“目标框架”。这里两个项目需要针对相同的框架。 - Travis
Nissim 的意思是右键单击 P2 的“引用”-> 添加引用,然后在项目下检查 P1,最后点击“确定”。这对我很有效。 - Dung

19

保罗·鲁恩是正确的,我刚刚尝试了构建该项目。 我创建了一个完整的解决方案来测试它是否可行。

我是在 VC# VS2008 中完成的

<<(只是帮助其他人阅读此评论的人)

步骤1:

创建名为 DoubleProject 的解决方案

步骤2:

在解决方案中创建名为 DoubleProjectTwo 的项目(选择解决方案文件,右键单击->添加->新项目)

现在我在同一个解决方案中有两个项目

步骤3:

如保罗·鲁恩所述。 在解决方案浏览器中转到引用(如果关闭,则在编译器的“视图”选项卡中)。 DoubleProjectTwo 是需要 DoubleProject 的函数/方法的项目,因此在 DoubleProjectTwo 右键单击引用,然后单击添加->项目->DoubleProject。

步骤4:

  

包括名称空间的指令:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DoubleProject; <------------------------------------------

namespace DoubleProjectTwo
{
    class ClassB
    {
        public string textB = "I am in Class B Project Two";
        ClassA classA = new ClassA();


        public void read()
        {
            textB = classA.read();
        }
    }
}

步骤5:

制作一些能够向我展示结果证明的东西:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DoubleProject
{
    public class ClassA    //<---------- PUBLIC class
    {
        private const string textA = "I am in Class A Project One";

        public string read()
        {
            return textA;
        }
    }
}

主要内容

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DoubleProjectTwo;  //<----- to use ClassB in the main

namespace DoubleProject
{
    class Program
    {
        static void Main(string[] args)
        {
            ClassB foo = new ClassB();

            Console.WriteLine(foo.textB);
            Console.ReadLine();
        }
    }
}

那应该就行了。

希望能对你有所帮助。

编辑:哎呀,我忘记调用方法来实际改变字符串了,不要犯相同的错误 :)


12
新手开发人员经常会问这个简单的问题,这是 Visual Studio IDE 的一个常见问题。很少有人回答具体的问题,通常批评问题或给出“猜测”的解决方案,这些解决方案并不能解决常见问题。第一个常见问题是,IDE 会引导你创建新项目,而不是将新文件(.java、.py、.cpp、.c)添加到现有解决方案中(默认情况下,它会创建一个新解决方案),除非你更改项目名称并添加到当前解决方案中。这个问题对于Python、Java、C#、C++和C项目文件夹都会出现。
新开发者选择“新建 > 项目 > 项目名称”,并将解决方案目录更改为“使用相同解决方案”,仍然会在同一解决方案空间中创建一个新的“项目”,但不在与当前用户界面文件或命令行文件相同的目录空间中,这仍然会导致“未找到包”错误,当构建和运行项目或解决方案时。这就是为什么上述关于导入包、类、方法和函数的编码建议仅在“库”文件或“分离行为”文件不仅位于相同的解决方案目录路径,而且还位于相同的“用户界面”或“命令行”应用程序目录空间时才有效(因此不答案问题)。当你使用 IDE 的新建 > 项目 > 项目类型命令添加另一个项目时,这种情况不会发生。问题在于新项目存储在与现有客户端或用户界面代码文件不同的目录中。为了在同一项目空间中创建一个新的“文件”,而不是新的项目,初学者需要做以下操作,这是 Microsoft 默认不会为你做的,甚至会误导你避开直觉上显而易见的方法。
1. 选择要将新行为导入的“应用程序”(从另一个文件)。 2. 选择项目 > 添加新项。 3. 选择“程序文件模板类型”,例如filetype.py、filetype.java、filetype.c、filetype.cpp、filetype.C#等,或库类文件类型(与创建新应用程序项目或创建新库项目时看到的启动文件选项不同)。 4. 在你的项目中创建一个具有默认名称的新文件。 5. 将文件的默认名称更改为类似于library.py或façade.java的名称。
现在,按照上面的评论所述,可以进行导入库或使用命名空间的代码建议,并且你不必更改路径语句或更改 Microsoft 不容易更改的解决方案路径和解决方案名称(即,你可以更改文件名或项目名称,但 IDE 不会自动更改项目路径或解决方案路径名称)。
以下是一个Python示例,但对于使用相应语言的包括、命名空间或使用代码命令在同一目录空间中查找其他类/项目的C#、Java或C/C++也适用。
在同一目录中从其他代码文件导入“hello world”应用程序文件。
请注意,在这个stackoverflow评论编辑器中,Python中的空格分隔符不会正确地转换到空格:
print ("test")

from CIXMPythonFacade import ClassA

c1=ClassA
c1.methodA()

from CIXMPythonFacade import functionA 

functionA()


class ClassName(object): 
         def __init__(object, parameter):
         object.parameter = value

包含你要导入的类、方法或函数的库文件或“门面”文件。

class class1(object):
    """description of class"""

class ClassA(object):
    print ("test2")
    def methodA():
        print ("test3")

def functionA ():
    print ("test4")
    return (0)


pass

现在你应该知道如何解决IDE引起的混乱了。如果要从同一目录空间中的另一个文件导入代码,则需要向其添加引用。

  1. 选择应用程序文件
  2. 选择项目>添加引用
  3. 选择正确目录路径可见的文件名(进行检查)
  4. 现在,该引用对解释器、代码检查器和/或编译器可用。

好的,现在您已经解决了这个问题,那么如何真正将两个单独的项目链接在同一个解决方案空间中呢?

  1. 您必须进入索引器或“智能感知”选项以及编译器/解释器,并在物理上检查或更改/添加目录路径语句,如果它们与指向“第二”项目或解决方案空间的路径不同,则进行更改。当您更改路径或更改路径变量以使其指向工作区和项目的特定位置时,编译器和代码分析器可以找到这些库、头文件、命名空间、项目或文件位置。
  2. 要删除错误创建的旧项目甚至更糟。您必须退出Visual Studio IDE,打开Windows资源管理器,转到工作区目录...documents\visualstudio xxx\solutionname\packagename选择文件或文件夹,右键单击并“删除”文件或文件夹。
  3. 当您重新进入IDE并选择打开解决方案或打开包/解决方案时,旧文件和解决方案/包名称将被删除,以及误导编译器和代码分析器查看旧目录的误导路径语句,即使您更改了文件名和项目名称,也不会随之更改目录路径。

Microsoft确实需要解决这些问题,以便您可以直观地在同一目录中创建大多数人想要创建的新文件,并通过从IDE中选择它们来删除解决方案。初学者对于有经验的开发人员来说非常灵活的目录路径语句感到非常沮丧,但对于其默认值来说却是不公平的。

希望这真正帮助了你这些新手,阻止有经验的开发人员为您提供错误答案,而这些错误答案对您没有用。他们假定您已经理解路径语句,只想键入正确的代码...这也是他们试图纠正您的代码但不帮助您解决问题的原因。这可能是stackoverflow上最常见的问题,也是错误答案持续出现的原因,这些错误答案对新程序员没有用。


总结一下这个答案(适用于VS 2017):在解决方案资源管理器中右键单击P1 >>> 添加... >>> 引用... >>> 项目 >>> 解决方案 >>> 选中P2复选框。 - andrew pate

8

第一步是通过以下方式使P2引用P1:

  • 右键单击项目,选择“添加引用”
  • 转到“项目”选项卡
  • 选择P1并点击“确定”

接下来,您需要确保P1中的类对P2可访问。最简单的方法是将它们设置为public

public class MyType { ... }

现在,您应该能够通过它们的完全限定名称在P2中使用它们。假设P1的命名空间是Project1,则以下操作将有效:

Project1.MyType obj = new Project1.MyType();

然而,更好的方法是添加一个 Project1 的 using,这样你就可以不用限定符使用这些类型。

using Project1;
...

public void Example() {
  MyType obj = new MyType();
}

6
如果您在一个解决方案文件夹中有两个项目,只需将一个项目的引用添加到另一个项目中。使用命名空间可以获取类。创建所需类的对象时,调用您想要的方法即可。
第一个项目:
class FirstClass()
{
   public string Name()
   {
      return "James";
   }
}

在这里添加指向第二个项目的引用

第二个项目:

class SeccondClass
{
    FirstProject.FirstClass obj=new FirstProject.FirstClass();
    obj.Name();
}

4
在项目P1中将该类设为public(如果它还不是public)。然后添加一个项目引用(而不是文件引用,我有时会犯这个错误)到P2。在P2的正确位置添加using语句并开始使用来自P1的类。
(提一下:将该类设为public的替代方案是将P2设置为P1的friend。然而,这不太可能是你想要的答案,因为它会产生一些后果。所以坚持上面的建议。)

2

假设你在项目2中的类名为MyClass。

显然,首先在项目1的引用中引用项目2,然后

using namespaceOfProject2;

// for the class calling bit:

namespaceOfProject2.MyClass project2Class = new namespaceOfProject2.MyClass();

无论何时你需要引用该类,你都需要输入 project2Class。此外,请确保该类是公共的。

2

我遇到了不同目标框架的问题。

我一切都做得正确,但就是不能在P2中使用引用。当我为P1和P2设置相同的目标框架后,它就像魔法般地工作了。

希望能对某人有所帮助。


我曾经遇到过同样的问题,出现了诸如“当前上下文中不存在名称...”、“无法解析符号...”等错误,直到我将项目的目标框架进行了更改。 (右键单击项目,然后转到“项目->属性->目标框架”以进行更改。) - sonnyb

1
你需要右键单击项目,选择添加 -> 引用... -> 项目并勾选你想引用的项目。
这样做的结果应该会在项目树的引用部分显示所引用的项目。
常见的用例涉及将测试框架(如 NUnit 项目)添加到你的解决方案中。然后,这个 NUnit 项目需要引用你的主要项目。为了做到这一点,步骤略有不同: 你需要右键单击 NUnit 项目,选择添加 -> 项目引用... -> 项目并勾选你想引用的项目。
这样做的结果应该会在 NUnit 项目树的“项目”部分下显示所引用的项目。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接