I have an ASP.NET web site project where I am using both VB.Net and C# class files. I have included separate sub folders in the App_Code directory for classes of each language.
我有一个ASP。NET网站项目,我正在使用这两个VB。Net和c#类文件。我在App_Code目录中为每种语言的类包含了单独的子文件夹。
However, while I can successfully make use of a C# class in a VB class, I cannot do the opposite: use a a 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. So this works well:
我可以在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
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". What am I missing here?
我得到一个错误,“无法找到类型或名称空间”VBTestClass。我错过了什么?
4 个解决方案
#1
2
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:
原因很简单,取决于你如何定义你的codesubdirectory,我认为你是这样做的:
<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.
但是,当这次VBCode首先编译时,您将失去在VB中使用任何CS类的能力。
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
谢谢
#2
1
The best way to look at using/Imports as a shortcut to skip fully qualifying namespaces. 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. For:
对于ASP中不同语言的代码文件。NET App_Code文件夹:不要使用它。:
- 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. If you're curious you can take a look at various files sitting in
除此之外,在visual studio和iis下运行此类项目时,还会发生许多有趣的事情。如果你很好奇,你可以看看里面的各种文件
\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. Good coding style would be to have all of them wrapped in a namespaces statements MyWebProject.VbCode and MyWebProject.CsCode for example. Then statements "using MyWebProject.VbCode" and "Imports MyWebProject.CsCode" would make more sense to the compiler.
通过这些无用的信息,我们现在可以知道,在同一个名称空间语句“导入CSTestClass”中有一个CSTestClass类并不是很有用。好的编码风格是将所有的名称空间语句都封装到MyWebProject中。VbCode MyWebProject。CsCode为例。然后使用MyWebProject声明”。VbCode”和“MyWebProject进口。CsCode对编译器来说更有意义。
#3
0
the using statement is for namespaces not class names, put the VBClass inside a namespace and then, use the "using" statement:
使用语句是针对名称空间而不是类名,将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;
...
#4
0
THe difference is in how the Imports
keyword works compared to the using
keyword.
区别在于导入关键字与使用关键字的工作方式。
The using
keyword can only be used to specify namespaces, while the Imports
keyword can also be used to specify classes.
使用关键字只能用于指定名称空间,而导入关键字也可以用于指定类。
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.
因此,导入CSTestClass指定类内的类、接口和枚举应该是可用的,但是该类不包含其中的任何一个,因此不需要导入语句。
When you try to use using VBTestClass
it won't work, as VBTestClass
is not a namespace.
当您尝试使用VBTestClass时,它不会工作,因为VBTestClass不是一个名称空间。
So, just remove the Imports
and using
statements, and it should work fine. As the classes are in the same assembly, they already know about each other.
因此,只需删除导入并使用语句,它应该可以正常工作。由于类在同一个程序集中,它们已经知道彼此。
#1
2
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:
原因很简单,取决于你如何定义你的codesubdirectory,我认为你是这样做的:
<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.
但是,当这次VBCode首先编译时,您将失去在VB中使用任何CS类的能力。
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
谢谢
#2
1
The best way to look at using/Imports as a shortcut to skip fully qualifying namespaces. 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. For:
对于ASP中不同语言的代码文件。NET App_Code文件夹:不要使用它。:
- 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. If you're curious you can take a look at various files sitting in
除此之外,在visual studio和iis下运行此类项目时,还会发生许多有趣的事情。如果你很好奇,你可以看看里面的各种文件
\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. Good coding style would be to have all of them wrapped in a namespaces statements MyWebProject.VbCode and MyWebProject.CsCode for example. Then statements "using MyWebProject.VbCode" and "Imports MyWebProject.CsCode" would make more sense to the compiler.
通过这些无用的信息,我们现在可以知道,在同一个名称空间语句“导入CSTestClass”中有一个CSTestClass类并不是很有用。好的编码风格是将所有的名称空间语句都封装到MyWebProject中。VbCode MyWebProject。CsCode为例。然后使用MyWebProject声明”。VbCode”和“MyWebProject进口。CsCode对编译器来说更有意义。
#3
0
the using statement is for namespaces not class names, put the VBClass inside a namespace and then, use the "using" statement:
使用语句是针对名称空间而不是类名,将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;
...
#4
0
THe difference is in how the Imports
keyword works compared to the using
keyword.
区别在于导入关键字与使用关键字的工作方式。
The using
keyword can only be used to specify namespaces, while the Imports
keyword can also be used to specify classes.
使用关键字只能用于指定名称空间,而导入关键字也可以用于指定类。
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.
因此,导入CSTestClass指定类内的类、接口和枚举应该是可用的,但是该类不包含其中的任何一个,因此不需要导入语句。
When you try to use using VBTestClass
it won't work, as VBTestClass
is not a namespace.
当您尝试使用VBTestClass时,它不会工作,因为VBTestClass不是一个名称空间。
So, just remove the Imports
and using
statements, and it should work fine. As the classes are in the same assembly, they already know about each other.
因此,只需删除导入并使用语句,它应该可以正常工作。由于类在同一个程序集中,它们已经知道彼此。