Преобразование класса Non-Generi c, расширенного классом Generi c, в C# в Java - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь преобразовать следующие классы в C# в Java.

Result - это не универсальный c класс, расширенный обобщенным c Result<T> class.

Их примеры использования следующие:

// 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?

Result.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 Cristobal Olivares ниже за ответ! Ниже приведены мои изменения:

ПРИМЕЧАНИЕ: Мне пришлось переименовать набранные функции fail и ok в failT и 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);    

1 Ответ

1 голос
/ 15 января 2020

Когда вы создаете класс C# generi c с 1 аргументом generi c, создается этот класс:

SomeClass`1

См. В чем смысл «апостроф + число» в типе объекта свойств с родовыми типами (например, «Collection`1»)? .

Таким образом, в то время как класс non-generi c называется SomeClass, версиями generi c являются SomeClass`1, SomeClass`2 и т. д. c (в зависимости от количества аргументов generi c).

Java Обобщения являются различными. Информация Generi c удаляется во время компиляции.

См. Удаляются ли обобщенные элементы компилятором во время компиляции .

Это означает, что non generi c и Версии generi c относятся к одному и тому же классу (SomeClass).

Итак, для этого варианта использования может потребоваться определить версию generi c. Эта версия будет работать для универсальных c и не универсальных c чехлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...