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. I have included separate sub folders in the App_Code directory for classes of each language.
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.
So, to illustrate, I might have two classes such as this:
Public Class VBTestClass
Public Su开发者_C百科b 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:
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:
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?
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#.
Consider the examples:
fully 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:
- they won't work when using Web Application project
- they will not compile when using csc or vbc compiler in continuous integration project outside of Visual Studio
- 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
\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.
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.
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>
<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.
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.
So for make it work with CS using VB, just simply change the folder setting order:
<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.
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 using statement is for namespaces not class names, put the VBClass inside a namespace and then, use the "using" statement:
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#:
using MyFoo;
...
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.
When you try to use using VBTestClass
it won't work, as VBTestClass
is not a namespace.
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.
精彩评论