所谓混用不是为了能够在一个代码文件中同时书写C#和vb.net语句
而是可以在一个程序中发挥两种语言不同的优势
或者说 更容易发挥码农对不同语言的理解和长处
C/S 下的混合编码不会有任何阻碍
假如你的主项目是vb.net 但是你突然想使用一个C#语法才有的特性 或者写某些语句的时候使用C#更得心应手
简单的在解决方案下创建一个C#的dll项目 代码敲进去 然后被vb.net项目引用就好了
示例如下
1> 创建一个vb.net控制台项目
2> 在解决方案下创建一个C#的winform Library项目
3> 在C#的Class1.cs下书写代码:
- using System;
- using System.Collections.Generic;
- namespace CSLib
- {
- public class Class1
- {
- public static IEnumerable<int> Iterator()
- {
- yield return 1;
- yield return 2;
- yield return 3;
- throw new InvalidOperationException("Custom Exception");
- }
- }
- }
4> 在vb.net项目下添加引用C#的项目
5> 在vb.net的Module1下书写代码:
- Imports CSLib
- Module Module1
- Sub Main()
- For Each i As Integer In Class1.Iterator()
- Console.WriteLine(i)
- Console.ReadKey()
- Next
- Console.ReadKey()
- End Sub
- End Module
6> 编译执行 如图
这里的IDE是vs2010 没有扩展vb.net的iterator关键字
不过迭代器语法已经在C#里实现很多年了
这里就是在vb中借助C#特性而获得的功能性便利
也能看出 在vb.net中 for each语句和C#的foreach功能是相同的
如果你想在同一个类中同时使用C#和vb.net语法特性从编译的角度实在难以实现
不过你可以在另一个项目中用扩展方法的特性给予实现 或者干脆写一个helper类被调用 通常的上下文应该允许被这样设计
如果你还想用另外一种语言调用一个自身的内部变量或方法...(嗯...哪来那么纠结的需求)
可以试着参考System.Runtime.CompilerServices.InternalsVisibleToAttribute特性 使程序集中的内部成员对指定程序集可见
B/S下的混合编码
web项目最后被编译也会生成dll文件 aspx/ashx等页面入口文件 以及js css等资源文件
so...我们很理所当然的认为不同CLR语言构造的webApp也可以合并成一个项目
示例如下
1> 创建一个空的解决方案 并分别添加vb.net c#两个web application
2> 在C#项目的WebForm1的前台和后台分别敲入如下代码
- <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="cs.WebForm1" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <asp:TextBox ID="txt1" runat="server"></asp:TextBox>
- <asp:Button ID="btn1" runat="server" UseSubmitBehavior="true" Text="提交" OnClick="btn1_Click" />
- </div>
- </form>
- </body>
- </html>
- using System;
- using System.Web;
- using System.Web.UI.WebControls;
- namespace cs
- {
- public partial class WebForm1 : System.Web.UI.Page
- {
- protected void Page_Load(object sender,EventArgs e)
- {
- }
- protected void btn1_Click(object sender,EventArgs e)
- {
- this.Session["user"] = txt1.Text.Trim();
- Response.Redirect("webform2.aspx");
- }
- }
- }
3> 把vb.net中的WebForm1重命名为WebForm2 并在前后台分别敲入如下代码
- <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm2.aspx.vb" Inherits="vb.WebForm2" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <asp:Label ID="lbl1" runat="server"></asp:Label>
- </div>
- </form>
- </body>
- </html>
- Public Class WebForm2
- Inherits System.Web.UI.Page
- Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs) Handles Me.Load
- If Session("user") IsNot Nothing Then
- lbl1.Text = Session("user")
- Else
- lbl1.Text = Session("未登录")
- End If
- End Sub
- End Class
4> 分别编译两个项目 并把两个项目的关键文件复制到一个独立文件夹中 在IIS中查看结果
4.1> 不过那样做很麻烦 我们可以利用VS的编译命令做到这一点
4.2> 在解决方案中新建一个webSite 注意是webSite不是webApplication
(二者的大致区别是webSite只是一个文件夹 执行行为包含着文件夹内所有文件 而webApp编译行为只包含着vs项目指定的文件 详细请参考相关资料)
可以任意指定一个文件夹(我使用了项目下新建的OutPut文件夹)
4.3> 对C#和vb.net项目分别添加生成后事件 这个设定分别在C#项目-属性-生成事件 和vb.net项目-属性-编译-生成事件 中
如上命令的作用是从两个项目的bin下复制dll 以及aspx文件到目的文件夹
- md "$(SolutionDir)Output\bin"
- xcopy /y "$(TargetDir)*.dll" "$(SolutionDir)Output\bin\"
- xcopy /y "$(ProjectDir)*.aspx" "$(SolutionDir)Output\"
当然未来还可以用命令来合并其他后缀的文件
4.4> 创建一个WebConfig文件 当然也可以从任意项目复制
4.5> 编译 把新建的webSite设为主项目 并且执行
如果没有意外 执行效果如下
在webform1中输入一个值 写入Session 然后在webForm2中读出来
这证实了IIS会正确加载对应的dll和aspx文件 即使aspx使用了不同语言书写(因为预编译行声明了page language)
但是事实上 我没有对任何一个项目添加了另外的项目引用-w- 两个项目完全没有依赖
以上可能要注意的地方就是页面名称冲突 或者两个程序集公开类型的完全限定名冲突 调用其他程序集的版本冲突 以及webconfig和资源文件的合并问题
这在实际工作中 两个项目合并可能会造成不可预知的后果 需要在奇怪的地方多加注意
结论
我们可以在需要的场合自由拼接由不同.net CLR语言编写的项目 合并工程 或者相互调用
在.net框架下 语言本身就是相通的 这种特性可以在很多时候发挥重要的作用
比如用C++/CLI下调用系统API 或者轻松移植C/C++的项目到.net (事实上LuaInterface工程就用的这种方式)
使用C#的语法到vb.net 合并或者无缝扩展不同语言编写的web app
总之 合理使用这种特性可以让编码的过程事半功倍
碎碎念
这是在第一季度就想好的主题...不过一直耽搁到现在才成文
题目背景是公司原有的网站是vb.net 1.1的年代构建的 不过一直在填补功能
如今又使用C#新开发了一套系统 一直想让两个网站合并
最初的方案是改写 移植 但是工作量甚大
后来研究了如何跨域传值 单点登录 不过最后也觉得意义不大 反而是提升了工作量
最后很无聊的一个尝试 证实了两个网站只要简单扔到一个文件夹就能交互了orz...
最后仔细想想 这也是理所当然的吧_(:з」∠)_