国内大多数大学的软件相关专业大多强制学生学习c和Java,但.net 的几个语言可以说是选学的。
由于visual studio在windows平台上使用相对方便,一些同学会在上大学的Java课之前自学.net开发技术。
这一类同学就需要一些代码转换技巧来帮助学习Java。
转载请说明作者Nukepayload2
在这之前我吐槽一下TinyMCE编辑器,它不能正确染色一些vb.net的关键字,比如Async, NameOf, Aggregate 。c#的某些关键字也不能正确染色,如__arglist。
由于我这学期才开始上Java课,代码中出现的错误欢迎大家指正。
1. 枚举类型
VB
Public Enum Direction Right = 1 DownRight Down DownLeft Left UpLeft Up UpRight End Enum
C#
public enum Direction { Down = 1, DownLeft, Left, UpLeft, Up, UpRight, Right, DownRight }
转换成Java是这样的。感觉跟c++/cli和c++/cx的enum class差不多。
如果原先的枚举比较长,最好写个小程序转换一下。
public enum Direction { Down(1), DownLeft(2), Left(3), UpLeft(4), Up(5), UpRight(6), Right(7), DownRight(8) private int __value; private Direction(int value) { this.__value = value; } @Override public String toString() { return String.valueOf(this.nCode); } }
那个__value是我抄.net参考源码的,如果看不顺眼可以改名。
2.异常
Java的异常如果不是RuntimeException这一类的,就得用Throws 声明,否则像AccessViolationException这一类错误一样只能在UnhandledException(ErrorListener)那里处理。
转换代码的时候写一堆Throws比较麻烦,写了一层就忘了下面那一层有什么异常了。
这个比较好办,只要不是致命的异常,那自定义异常就都继承RuntimeException好了。自带的几个需要用Throws的异常用ErrorListener拦截。
class PointOutOfScreenException extends RuntimeException{ public PointOutOfScreenException(){ super("点出屏幕了..."); } }
3.标识符类型的推断
VB
Dim a = New StringBuilder
C#
var a = new StringBuilder();
转换成Java就用复制粘贴大法,把类名复制一下然后粘贴到开头
StringBuilder a = new StringBuilder();
4. c#不安全模式, vb和f#各种调运行库的独有运算符, 动态, async, await, linq, 无符号类型 .......
VB
Async Function LoadImages(device As CanvasDevice) As Task forestTiles = Await SpriteSheet.LoadAsync(device, $"SpriteSheets/ForestTiles{NameOf(ImageID)}.png", New Vector2(64, 64), Vector2.Zero) wizardWalk = Await SpriteSheet.LoadAsync(device, "SpriteSheets/WizardWalkRight.png", New Vector2(128, 192), New Vector2(64, 150)) wizardIdle = Await SpriteSheet.LoadAsync(device, "SpriteSheets/WizardIdleRight.png", New Vector2(128, 192), New Vector2(64, 150)) End Function
C#
async Task LoadImages(CanvasDevice device) { forestTiles = await SpriteSheet.LoadAsync(device, $"SpriteSheets/ForestTiles{nameof(ImageID)}.png", new Vector2(64, 64), Vector2.Zero); wizardWalk = await SpriteSheet.LoadAsync(device, "SpriteSheets/WizardWalkRight.png", new Vector2(128, 192), new Vector2(64, 150)); wizardIdle = await SpriteSheet.LoadAsync(device, "SpriteSheets/WizardIdleRight.png", new Vector2(128, 192), new Vector2(64, 150)); }
VB
Public Function CalculateClipGeometry(resource As ICanvasResourceCreator, SourcePoint As Vector2, Geometies As CanvasGeometry(), ScreenSize As Size) As CanvasGeometry Dim geos = Aggregate geo In Geometies Let Lines = Aggregate tes In geo.Tessellate From ln In {New LineSegment(tes.Vertex1, tes.Vertex2), New LineSegment(tes.Vertex1, tes.Vertex3), New LineSegment(tes.Vertex3, tes.Vertex2)} Select ln Distinct Into ToArray Select Rays = Aggregate tes In geo.Tessellate From light In {New LineSegment(SourcePoint, tes.Vertex1), New LineSegment(SourcePoint, tes.Vertex2), New LineSegment(SourcePoint, tes.Vertex3)} Where Not (Aggregate l In Lines Where light.RayToBoundary(ScreenSize).HasIntersection(l) Into Any) Select light Into ToArray Where Rays.Length >= 2 AndAlso Rays(0).Name Like "Ln*" Let Fir = Rays.First Select Arr = Aggregate ln In Rays Order By ln.Angle(Fir) Into ToArray Select CanvasGeometry.CreatePolygon(resource, {Arr.First.Point2, Arr.First.RayToBoundary(ScreenSize).Point2, Arr.Last.RayToBoundary(ScreenSize).Point2, Arr.Last.Point2}) Into ToArray Return geos.Union End Function
C#
public unsafe void AddThree(__arglist) { var args = new ArgIterator(__arglist); var a = (byte*)TypedReference.ToObject(args.GetNextArg()); *a+=3; }
Java
// TODO: 自己重新写吧。直接转换这种代码反而浪费时间!
5.事件和委托
遇到这个没有第四条那么极端,因为Java有用于实现接口的匿名类。
VB
Event Slide(sender As Object, e As SlideEventArgs)
C#
delegate void SlideEventHandler(object sender, SlideEventArgs e); event SlideEventHandler Slide;
Java
interface SlideEventHandler{ void slide(Object sender, SlideEventArgs e); }
VB 处理事件
Sub xx_Slide(sender As Object, e As SlideEventArgs) Handles xx.Slide ... End Sub
C# 处理事件
类名() { xx.Slide += xx_Slide; } void xx_Slide(object sender, SlideEventArgs e) { ... }
VB 使用Lambda表达式处理事件
AddHandler xx.Slide, Sub(sender, e) ...
C# 使用Lambda表达式处理事件
xx.Slide += (sender, e) => ... ;
Java 处理事件
xx.setSlideListener(new SlideEventHandler(){ void slide(Object sender, SlideEventArgs e){ ... } });
我现在还没看JDK 1.8的Lambda表达式能不能用来处理事件和完成委托,所以不提供这方面的Java代码。
我还要上课呢,这次就写到这里吧。喜欢Java的可以找出描述不合理的地方,但是请勿喷。