简体   繁体   English

在C#类中使用同一ASP.NET网站项目中的VB类

[英]Using a VB class from the same ASP.NET web site project in a C# class

I have an ASP.NET web site project where I am using both VB.Net and C# class files. 我有一个ASP.NET网站项目,我使用VB.Net和C#类文件。 I have included separate sub folders in the App_Code directory for classes of each language. 我在App_Code目录中包含了单独的子文件夹,用于每种语言的类。

However, while I can successfully make use of a C# class in a VB class, I cannot do the opposite: use aa VB class in a C# class. 但是,虽然我可以在VB类中成功使用C#类,但我不能做相反的事情:在C#类中使用VB类。

So, to illustrate, I might have two classes such as this: 因此,为了说明,我可能有两个类,如:

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;
    }

}

I can make use of the CS class in my VB class, with the "Imports" statement. 我可以使用“Imports”语句在VB类中使用CS类。 So this works well: 所以这很好用:

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

But making use of the VB class in my C#, with the "using" statement, does not work: 但是使用“使用”语句在我的C#中使用VB类不起作用:

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

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

I get an error that "the type or namespace "VBTestClass" could not be found". 我收到一个错误,“无法找到”类型或命名空间“VBTestClass”。 What am I missing here? 我在这里错过了什么?

I think I found the problem and seems without a reflection you can't do it as a cross reference. 我想我发现了问题并且似乎没有反映你不能作为交叉参考。

The reason is pretty simple, depends how the orders you define your codeSubDirectories, I think you made it this way: 原因很简单,取决于你定义codeSubDirectories的顺序,我想你是这样做的:

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

As we know each directory will be build to different assembly, and they will be build one by one from top to bottom based on your settings. 我们知道每个目录都将构建到不同的程序集,并且它们将根据您的设置从上到下逐个构建。

So as you have CSCode folder defined first, it will be built first, and then compiler start to build VBCode, so using the CS class is OK as it can find the assembly to reference. 因此,当您首先定义CSCode文件夹时,它将首先构建,然后编译器开始构建VBCode,因此使用CS类是可以的,因为它可以找到要引用的程序集。

But if you do it reversely, as you mentioned to reference VB code in CS, it firstly build CSCode folder and at that time the assembly of VBCode does not exist so it throw exceptions. 但是,如果你反过来,正如你提到的那样在CS中引用VB代码,它首先构建CSCode文件夹,那时VBCode的程序集不存在,因此它会抛出异常。

So for make it work with CS using VB, just simply change the folder setting order: 因此,为了使它与CS一起使用VB,只需更改文件夹设置顺序:

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

But then you will lose the ability to use any CS class in VB as this time VBCode compile first. 但是那时你将失去在VB中使用任何CS类的能力,因为这次VBCode首先编译。

So my suggestion is go with reflection to load it at run time so that compiler can let you go. 所以我的建议是反思在运行时加载它,以便编译器可以让你离开。

Hope my explanation is clear enough. 希望我的解释清楚。

Thanks 谢谢

The best way to look at using/Imports as a shortcut to skip fully qualifying namespaces. 查看使用/ Imports作为跳过完全限定名称空间的快捷方式的最佳方法。 The behaviour is the same across vb and c#. vb和c#的行为相同。

Consider the examples: 考虑一下例子:

fully qualyfying: 完全qualyfying:

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

skip the namespaces: 跳过命名空间:

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

and a little shortcut trick 还有一个小捷径

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

and a replacement trick: 和替代技巧:

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

As for code files in different languages in ASP.NET App_Code folder: DO NOT USE IT. 对于ASP.NET App_Code文件夹中不同语言的代码文件:不要使用它。 For: 对于:

  • they won't work when using Web Application project 使用Web应用程序项目时它们不起作用
  • they will not compile when using csc or vbc compiler in continuous integration project outside of Visual Studio 在Visual Studio之外的持续集成项目中使用csc或vbc编译器时,它们不会编译
  • and they will generally give you a lot of pain on infrastructure side of things. 他们通常会在基础设施方面给你带来很多痛苦。

Best way is to create separate Class Library projects for respective language and use them. 最好的方法是为各自的语言创建单独的类库项目并使用它们。

On top of it there are a lot of interesting things going on when running such project from under visual studio and iis. 最重要的是,在visual studio和iis下运行这样的项目时会发生很多有趣的事情。 If you're curious you can take a look at various files sitting in 如果你很好奇,你可以看一下坐在里面的各种文件

\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\{project name}\{tempname} 

it should give you a good idea how asp.net engine combines the code files for aspx pages. 它应该让你很好地了解asp.net引擎如何组合aspx页面的代码文件。

Aimed with that useless information we can now tell that having a CSTestClass class in the same namespace statement "Imports CSTestClass" is not really useful. 针对这些无用的信息,我们现在可以告诉我们在相同的命名空间语句“Imports CSTestClass”中使用CSTestClass类并不是很有用。 Good coding style would be to have all of them wrapped in a namespaces statements MyWebProject.VbCode and MyWebProject.CsCode for example. 好的编码风格是将所有这些包装在命名空间语句MyWebProject.VbCode和MyWebProject.CsCode中。 Then statements "using MyWebProject.VbCode" and "Imports MyWebProject.CsCode" would make more sense to the compiler. 然后语句“使用MyWebProject.VbCode”和“Imports MyWebProject.CsCode”对编译器更有意义。

the using statement is for namespaces not class names, put the VBClass inside a namespace and then, use the "using" statement: 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

now in c#: 现在在c#中:

using MyFoo;

...

THe difference is in how the Imports keyword works compared to the using keyword. 不同之处在于Imports关键字与using关键字相比的工作方式。

The using keyword can only be used to specify namespaces, while the Imports keyword can also be used to specify classes. using关键字只能用于指定名称空间,而Imports关键字也可用于指定类。

So, Imports CSTestClass specifies that classes, interfaces and enums inside that class should be available, but the class doesn't contain any of those, so the Imports statement is not needed. 因此, Imports CSTestClass指定Imports CSTestClass中的类,接口和枚举应该可用,但该类不包含任何类,因此不需要Imports语句。

When you try to use using VBTestClass it won't work, as VBTestClass is not a namespace. 当您尝试using VBTestClass ,它将无法工作,因为VBTestClass不是命名空间。

So, just remove the Imports and using statements, and it should work fine. 因此,只需删除Importsusing语句,它应该可以正常工作。 As the classes are in the same assembly, they already know about each other. 由于这些类在同一个程序集中,因此它们已经相互了解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM