繁体   English   中英

通用子类和类型推断-这是唯一的方法吗?

[英]Generic child class and type inference - is this the only way?

更新:我最终在C#中使用了有关错误处理的功能方法的本文http://enterprisecraftsmanship.com/2015/03/20/functional-c-handling-failures-input-errors/

我有一个非泛型基类和一个继承该基类的泛型类。 它们的目的是为“成功或失败”的想法建模-有时某些情况将返回“我成功”结果,而有时某些情况将返回“我成功,这就是结果”,尽管这与问题。

public class OperationResult
{
    public bool Successful { get; protected set; }
    public string FailureMessage { get; protected set; }
    public Exception Exception { get; protected set; }

    protected OperationResult() { }

    public static OperationResult Success()
    {
        Console.WriteLine(1);
        return new OperationResult()
        {
            Successful = true
        };
    }
    // not including failure part for clarity
}

public class OperationResult<T> : OperationResult
{
    public T Result { get; private set; }

    private OperationResult () { }

    public static OperationResult<T> Success(T result)
    {
        Console.WriteLine(2);
        return new OperationResult<T>()
        {
            Successful = true,
            Result = result
        };
    }
}

我现在遇到的情况是,因为两个方法的名称相同,所以编译器无法再推断类型,因此我需要指定类型。 例如:

OperationResult.Success(); // Valid
OperationResult.Success("test"); // Invalid
OperationResult<string>.Success("test"); // Valid - wouldn't usually need to specify T

我忍不住觉得自己做错了什么,或者有更好的方法可以做到这一点。

  1. 有没有办法让编译器在不指定我的情况下仍然推断类型?
  2. 这是我第一次看到Thing<T>.SomeMethod()语法(不带方括号() )-我Thing<T>.SomeMethod()是完全错误的吗?

编辑 :没有静态便利方法的第二次尝试。

new OperationResult().Success();
new OperationResult<string>().Success("something was successful");

public class OperationResult
{
    public bool Successful { get; protected set; }
    public string FailureMessage { get; protected set; }
    public Exception Exception { get; protected set; }

    public OperationResult() { }

    public OperationResult Success()
    {
        Console.WriteLine(1);
        return new OperationResult()
        {
            Successful = true
        };
    }
}

public class OperationResult<T> : OperationResult
{
    public T Result { get; private set; }

    public OperationResult () { }

    public OperationResult<T> Success(T result)
    {
        Console.WriteLine(2);
        return new OperationResult<T>()
        {
            Successful = false,
            Result = result
        };
    }
}

看起来您尝试使用继承来实现两种不同类型的操作。 如果我正确地理解了该应用程序,并且确实进行了编译,那么即使只有一个有效,您也可以在任何操作上调用任一Success方法。 也就是说,一个操作将返回结果或将不返回结果。 因此,您有2种不同的操作。

编译器问题是设计问题的征兆。

设计您的类,以便只能以正确的方式使用它们。 也就是说,永远不要公开不应调用的方法。 这里的目的是要有2个成功方法,但只有一个有效。 那是代码的味道。

我认为问题出在这里对继承的不当使用。

方法:

  1. 抽象基类和2个继承的类。 基类中没有成功方法。
  2. 2个类,一个公共接口和2个派生接口。 在构造函数中注入通用功能。

如果您重视单元可测试的代码,则最好使用后者。 两者都是有效的,我稍后再做。

这是您的操作方式:

public class OperationResult
{
    public bool Successful { get; protected set; }
    public string FailureMessage { get; protected set; }
    public Exception Exception { get; protected set; }

    protected OperationResult() { }

    public static OperationResult Success()
    {
        Console.WriteLine(1);
        return new OperationResult() { Successful = true };
    }

    public static OperationResult<T> Success<T>(T result)
    {
        Console.WriteLine(2);
        return new OperationResult<T>(result) { Successful = true };
    }
}

public class OperationResult<T> : OperationResult
{
    internal OperationResult(T result) { Result = result; }

    public T Result { get; private set; }
}

您的所有三个成功代码行现在都可以运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM