首页 > 解决方案 > 将 C# 中由泛型类扩展的非泛型类转换为 Java

问题描述

我正在尝试将 C# 中的以下类转换为 Java。

Result是由泛型类扩展的非泛型Result<T>类。

它们的示例用法如下:

// When we only care if the operation was successful or not.
Result result = Result.OK();

// When we also want to store a value inside the Result object.
Result<int> result = Result.OK<int>(123);    

在 Java 中,每个类都需要在自己的文件中定义(除非它们是嵌入的)。

不幸的是,我找不到让基类和扩展类像在 C# 中那样共享相同名称的方法。

有没有办法将以下 C# 代码转换为 Java?

结果.cs:

using System;

namespace MyProject
{
    public class Result
    {
        private bool _isSuccess;
        private string _errorMsg = "";

        public bool IsSuccess()
        {
            return _isSuccess;
        }

        public bool IsFailure()
        {
            return !_isSuccess;
        }

        public string ErrorMsg()
        {
            return _errorMsg;
        }

        public Result(bool isSuccess, string errorMsg)
        {
            bool errorMsgIsEmpty = string.IsNullOrEmpty(errorMsg);

            if (isSuccess && !errorMsgIsEmpty)
            {
                throw new Exception("cannot have error message for successful result");
            }
            else if (!isSuccess && errorMsgIsEmpty)
            {
                throw new Exception("must have error message for unsuccessful result");
            }

            _isSuccess = isSuccess;

            if (!errorMsgIsEmpty)
            {
                _errorMsg = errorMsg;
            }
        }

        public static Result Fail(string errorMsg)
        {
            return new Result(false, errorMsg);
        }

        public static Result<T> Fail<T>(string errorMsg)
        {
            return new Result<T>(default(T), false, errorMsg);
        }

        public static Result OK()
        {
            return new Result(true, "");
        }

        public static Result<T> OK<T>(T value)
        {
            return new Result<T>(value, true, "");
        }
    }

    public class Result<T> : Result
    {
        private T _value;

        public T Value()
        {
            return _value;
        }

        public Result(T value, bool isSuccess, string errorMsg) : base(isSuccess, errorMsg)
        {
            _value = value;
        }
    }
}

更新:特别感谢下面@Juan Cristóbal Olivares 的回答!以下是我的更改:

注意:我不得不将 typedfailokfunctionsfailT和 ,okT因为 Java 不允许仅通过返回类型不同的函数。

结果.java:

public class Result<T> {
    private boolean isSuccess;
    private String errorMsg = "";
    private T value;

    public boolean isSuccess() {
        return isSuccess;
    }

    public boolean isFailure() {
        return !isSuccess;
    }

    public String errorMsg() {
        return errorMsg;
    }

    public T value() {
        return value;
    }

    public Result(boolean isSuccess, String errorMsg) throws Exception {
        boolean errorMsgIsEmpty = StringUtil.IsNullOrEmpty(errorMsg);

        if (isSuccess && !errorMsgIsEmpty) {
            throw new Exception("cannot have error message for successful result");
        } else if (!isSuccess && errorMsgIsEmpty) {
            throw new Exception("must have error message for unsuccessful result");
        }

        this.isSuccess = isSuccess;

        if (!errorMsgIsEmpty) {
            this.errorMsg = errorMsg;
        }
    }

    public Result(T value, boolean isSuccess, String errorMsg) throws Exception {
        this(isSuccess, errorMsg);
        this.value = value;
    }

    public static Result<?> fail(String errorMsg) throws Exception {
        return new Result<>(false, errorMsg);
    }

    public static <T> Result<T> failT(String errorMsg) throws Exception {
        return new Result<T>(null, false, errorMsg);
    }

    public static Result<?> ok() throws Exception {
        return new Result<>(true, "");
    }

    public static <T> Result<T> okT(T value) throws Exception {
        return new Result<T>(value, true, "");
    }
}

示例用法:

// When we only care if the operation was successful or not.
Result<?> result = Result.ok();

// When we also want to store a value inside the Result object.    
Result<Integer> result = Result.okT(123);    

标签: javac#genericsinheritance

解决方案


当您使用 1 个泛型参数创建 C# 泛型类时,将生成此类:

SomeClass`1

请参阅具有泛型的属性的对象类型(例如“Collection`1”)中“撇号+数字”的含义是什么?.

因此,当非泛型类被命名SomeClass时,泛型版本是SomeClass`1,SomeClass`2等(取决于泛型参数的数量)。

Java 泛型是不同的。通用信息在编译时被删除。

请参阅编译器在编译时是否删除了泛型

这意味着非泛型和泛型版本只是同一个类 ( SomeClass)。

因此,对于这个用例,您可能只需要定义通用版本。此版本适用于通用和非通用情况。


推荐阅读