【持续更新】把.net代码转换为java代码的注意事项

国内大多数大学的软件相关专业大多强制学生学习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("点出屏幕了...");
    }
}

 需要注意的是

<1> Java不支持异常筛选器。

<2> Java不支持MSIL中的 try...catch...fault (在VB中为Using, 在C#中为using)

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代码。

6.重要的修饰符

访问级别修饰符

VB C# Java
Private private private
Protected protected 不支持
Protected Friend protected internal protected
Friend internal 这是默认值
Public public public

继承和多态相关的修饰符

VB C# Java
MustInherit abstract abstract
MustOverride abstract abstract
Overridable virtual 这是默认值
Overrides override @override
Overloads overload 这是默认值
Shadows new 不支持
NotOverridable sealed final

成员类别标识符

VB C# Java
Class class class
Module

[StandardModule()]

static sealed class

final class (不准确)
Event event 不支持
Custon Event event 不支持
Delegate delegate 不支持
Property 已省略 不支持
Dim 已省略 已省略
Interface interface interface
Function 已省略 已省略
Sub 已省略 已省略

7.参数传递相关

下面列出参数传递方式比较

VB C# Java
ByVal (这是默认值) 这是默认值 这是默认值
ByRef ref 不支持
ParamArray params ...
不支持 __arglist 不支持
不支持 * (直接传指针) 不支持
<In> in 这是默认值
<Out> out 不支持

8.属性

Java不支持属性,所以必须手动写方法来封装私有字段 :(

VB

Public Property LastUpdateTimestamp As Date

C#

public DateTime LastUpdateTime { get; set;}

Java

private DateTime lastUpdateTime;
public DateTime getLastUpdateTime(){
    return lastUpdateTime;
}
public void setLastUpdateTime(DateTime value){
    lastUpdateTime = value;
}

这次就写到这里吧。喜欢Java的可以找出描述不合理的地方,但是请勿喷。

原文地址:https://www.cnblogs.com/Nukepayload2/p/dotnet_java_conv.html