【问题标题】:Using a VB class from the same ASP.NET web site project in a C# class在 C# 类中使用来自同一 ASP.NET 网站项目的 VB 类
【发布时间】:2011-03-20 03:26:13
【问题描述】:

我有一个 ASP.NET 网站项目,我在其中同时使用 VB.Net 和 C# 类文件。我在 App_Code 目录中为每种语言的类包含了单独的子文件夹。

然而,虽然我可以成功地在 VB 类中使用 C# 类,但我不能做相反的事情:在 C# 类中使用 VB 类。

所以,为了说明,我可能有两个这样的类:

Public Class VBTestClass
    Public Sub New()
    End Sub

    Public Function HelloWorld(ByVal Name As String) As String
        Return Name
    End Function
End Class

public class CSTestClass
{
    public CSTestClass()
    {
    }
    public string HelloWorld(string Name)
    {
        return Name;
    }

}

我可以通过“Imports”语句在我的 VB 类中使用 CS 类。所以这很好用:

Imports CSTestClass
Public Class VBTestClass
    Public Sub New()
    End Sub

    Public Function HelloWorld(ByVal Name As String) As String
        Return Name
    End Function

  Private Sub test()
      Dim CS As New CSTestClass
      CS.HelloWorld("MyName")
   End Sub
End Class

但是在我的 C# 中使用 VB 类,使用“using”语句,不起作用:

using VBTestClass;
public class CSTestClass
{
      public CSTestClass()
      {
  }

     public string HelloWorld(string Name)
    {
        return Name;
    }
}

我收到“找不到类型或命名空间“VBTestClass”的错误”。我在这里想念什么?

【问题讨论】:

    标签: c# asp.net vb.net


    【解决方案1】:

    using 语句用于命名空间而不是类名,将 VBClass 放在命名空间中,然后使用“using”语句:

    Namespace MyFoo
    Public Class VBTestClass 
        Public Sub New() 
        End Sub 
    
        Public Function HelloWorld(ByVal Name As String) As String 
            Return Name 
        End Function 
    End Class
    End Namespace
    

    现在在 c# 中:

    using MyFoo;
    
    ...
    

    【讨论】:

      【解决方案2】:

      using 关键字相比,Imports 关键字的工作方式有所不同。

      using关键字只能用来指定命名空间,而Imports关键字也可以用来指定类。

      因此,Imports CSTestClass 指定该类中的类、接口和枚举应该可用,但该类不包含任何这些,因此不需要 Imports 语句。

      当您尝试使用 using VBTestClass 时,它不起作用,因为 VBTestClass 不是命名空间。

      所以,只需删除 Importsusing 语句,它应该可以正常工作。由于这些类在同一个程序集中,因此它们已经相互了解。

      【讨论】:

      • 非常感谢 - 非常有用的信息。但是,我尝试将 VB 类包装在命名空间中(根据前面的答案),并删除 Imports 和 Using 语句(只是直接使用这些类,假设他们会知道彼此在相同的组件)。但是,我仍然遇到同样的问题...
      【解决方案3】:

      将 using/Imports 视为跳过完全限定命名空间的捷径的最佳方式。在 vb 和 c# 中的行为是相同的。

      考虑例子:

      完全合格:

      void DoSomething()
      {
          var p = new Interfaces.CPDATA.DataHolders.Placement(); 
      }
      

      跳过命名空间:

      using Interfaces.CPDATA.DataHolders; 
      void DoSomething()
      {
          var p = new Placement(); 
          var t = new Trade(); 
      }    
      

      还有一个捷径

      using data = Interfaces.CPDATA.DataHolders; 
      void DoSomething()
      {
          var p = new data.Placement(); 
          var t = new data.Trade(); 
      }   
      

      还有一个替换技巧:

      using t = Interfaces.CPDATA.DataHolders.Placement; 
      void DoSomething()
      {
          var p = new t(); // happy debagging
      }   
      

      对于 ASP.NET App_Code 文件夹中不同语言的代码文件:不要使用它。对于:

      • 它们在使用 Web 应用程序项目时不起作用
      • 在 Visual Studio 之外的持续集成项目中使用 csc 或 vbc 编译器时,它们将无法编译
      • 而且它们通常会给您在基础设施方面带来很多痛苦。

      最好的方法是为各自的语言创建单独的类库项目并使用它们。

      除此之外,在 Visual Studio 和 iis 下运行此类项目时会发生很多有趣的事情。如果您很好奇,可以查看位于

      中的各种文件
      \Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\{project name}\{tempname} 
      

      它应该让您了解 asp.net 引擎如何组合 aspx 页面的代码文件。

      针对那些无用的信息,我们现在可以看出,在同一个命名空间语句“Imports CSTestClass”中拥有一个 CSTestClass 类并不是真正有用的。好的编码风格是将它们都包装在命名空间语句中,例如 MyWebProject.VbCode 和 MyWebProject.CsCode。 Then 语句“使用 MyWebProject.VbCode”和“Imports MyWebProject.CsCode”对编译器更有意义。

      【讨论】:

        【解决方案4】:

        我认为我发现了问题,并且似乎没有反思,您无法将其作为交叉引用。

        原因很简单,看你定义codeSubDirectories的顺序,我想你是这样弄的:

        <codeSubDirectories>
            <add directoryName="CSCode"/>
            <add directoryName="VBCode"/>
        </codeSubDirectories>
        

        正如我们所知,每个目录都将构建到不同的程序集,并且它们将根据您的设置从上到下一一构建。

        既然你先定义了CSCode文件夹,它会先被编译,然后编译器开始编译VBCode,所以使用CS类是可以的,因为它可以找到要引用的程序集。

        但是如果你反过来做,就像你提到在CS中引用VB代码,它首先建立CSCode文件夹,当时VBCode的程序集不存在,所以它抛出异常。

        所以要让它在使用 VB 的 CS 上工作,只需更改文件夹设置顺序:

        <codeSubDirectories>
            <add directoryName="VBCode"/>
            <add directoryName="CSCode"/>
        </codeSubDirectories>
        

        但是你将失去在VB中使用任何CS类的能力,因为这次VBCode首先编译。

        所以我的建议是在运行时使用反射来加载它,这样编译器就可以放手了。

        希望我的解释足够清楚。

        谢谢

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-19
          • 1970-01-01
          相关资源
          最近更新 更多