【问题标题】:Pattern for exposing non generic and generic Class暴露非泛型和泛型类的模式
【发布时间】:2017-12-28 17:51:48
【问题描述】:

我已经为我的方法实现了一个通用的操作结果,它看起来像这样

public class OperResult
{
    public string ErrorCode { get; private set; }
    public string Message { get; private set; }
    public object Data { get; private set; }
    public bool Ok { get; private set; }
    public string IncidentNumber { get; set; }

    public static OperResult Success(Object data = null)
    {
        return new OperResult(data);
    }
}

和使用泛型一样的运算结果

public class OperResult<T>
{
    public string ErrorCode { get; private set; }
    public string Message { get; private set; }
    public T Data { get; private set; }
    public bool Ok { get; private set; }
    public string IncidentNumber { get; private set; }

    public static OperResult<T> Success(T data = null)
    {
        return new OperResult<T>(data);
    }
}

有没有什么办法可以将这两种实现结合起来,同时提供这个类的通用和非通用版本?


编辑添加更多关于类型使用的信息:

我想轻松创建返回此类型的函数,例如我希望能够创建以下函数:

OperResult MakeAction()
OperResult<int> GetCount()

如果我使用继承OperResult:OperResult&lt;Object&gt;,那么OperResult.Suceess() 将产生OperResult&lt;Object&gt;,以下将产生编译错误:

OperResult MakeAction(){
  return OperResult.Suceess(); //Cannot convert OperResult<Object> to OperResult
}

GitHub link to OperResult

【问题讨论】:

  • 你认为它应该是什么样子?顺便说一句:似乎非泛型实际上是OperResult&lt;object&gt;
  • 还有鼓声,为什么?
  • 已经在cmetsclass OperResult: OperResult&lt;object&gt; { }中提到了

标签: c# generics


【解决方案1】:

正如 cmets 中已经提到的,非泛型似乎是 OperResult&lt;object&gt;

最初沿着这条路线走,但事实证明它不适合所需的用例。 将其切换为从非泛型派生泛型并提供新的 Data 属性。

public class OperResult {

    protected OperResult(object data) {
        this.Data = data;
    }

    public string ErrorCode { get; protected set; }
    public string Message { get; protected set; }
    public object Data { get; protected set; }
    public bool Ok { get; protected set; }
    public string IncidentNumber { get; protected set; }

    public static OperResult Success(object data = null) {
        return new OperResult(data ?? new object());
    }

    public static OperResult<T> Success<T>(T data) {
        return new OperResult<T>(data);
    }
}

public class OperResult<T> : OperResult {

    public OperResult(T data)
        : base(data) {
    }

    public new T Data { get; protected set; }
}

这允许以下语法

int data = 10;
var result = OperResult.Success(data);
//result is OperResult<int>

【讨论】:

  • OperResult.Success();OperResult&lt;Object&gt; 而不是 OperResult。这样您就无法创建返回 OperResult 的函数
  • 但鉴于OperResultOperResult&lt;Object&gt;,结果是有效的。你仍然可以创建一个重载。
  • 如果这是您的建议,(OperResult)OperResult&lt;object&gt; 将产生运行时错误。
  • @MenelaosVergis 我有一个想法,现在正在研究一个新的角度
  • @MenelaosVergis 看看新方法
猜你喜欢
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-16
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
相关资源
最近更新 更多