【问题标题】:Is there another way to change the return type of a static method of an abstract class based on the derived class type in C#?是否有另一种方法可以根据 C# 中的派生类类型更改抽象类的静态方法的返回类型?
【发布时间】:2021-02-10 00:01:36
【问题描述】:

编辑:这个问题的主要目的是更深入地了解 C# 和 OOP。请记住,我并不是想用这段代码解决一个特定的问题,而只是想了解一切是如何工作的。

我有办法做到这一点,但我想知道是否还有其他方法。

public abstract class ModelBase
{

    private const string ERROR = "Error";

    public string Status { get; set; }
    public string StatusDescription { get; set; }

    public static T Error<T>(string errorDescription)
        where T : ModelBase, new()
    {
        var model = new T
        {
            Status = ERROR,
            StatusDescription = errorDescription
        };
        return model;
    }

}

然后调用它:

return ModelBase.Error<ApplicationInit>("Failed to retrieve application segment.");

其中“ApplicationInit”是 ModelBase 的派生类。

如果相反,我可以调用:

return ApplicationInit.Error("Failed to retrieve application segment.");

...并且代码将能够告诉派生类是什么。

IDK,也许这不可能……

【问题讨论】:

  • 这个方法需要通用吗?您可以创建 ModelBase 的私有派生类并返回它。 public static ModelBase Error(string errorDescription)
  • 很多 种替代品,但如果有任何一种您认为合适,那就没法说了。这个问题太宽泛了,不适合 Stack Overflow。也就是说,您现在所拥有的似乎是一种合理的“工厂方法”方法,我看不出ApplicationInit.Error 在任何实质上都比Error&lt;ApplicationInit&gt; 更可取。
  • Curiously Recurring Template Pattern 可能在这里工作。所以你声明 class ModelBase&lt;T&gt; where T : ModelBase&lt;T&gt; 看起来很奇怪但有效
  • 你的第二个例子,这个“超酷的方式”可以用Extension Methods实现

标签: c# oop


【解决方案1】:

没有。当您声明 static 方法时,它只有一个版本*。调用 ModelBase.Error&lt;ApplicationInit&gt;("") 和调用 ApplicationInit.Error&lt;ApplicationInit&gt;("") 都将编译为完全相同的字节码,并且一组好的分析器会用警告标记后者。

您可以在ApplicationInit 中使用新的静态方法隐藏Error,但这将是每个新子类的手动过程。没有办法^比你已经拥有的更概括它。


* 一个泛型方法可以为不同的类型参数产生不同的字节码,但所有这些方法都是ModelBase 的静态成员,而不是任何子类。

^ 您可以编写一个源代码生成器来生成这些静态方法,但这比直接使用通用的ModelBase.Error&lt;T&gt; 方法要多得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-12
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 2011-03-05
    • 2018-10-19
    相关资源
    最近更新 更多