首页 > 解决方案 > 在 C# 中使用泛型多态性时,如何防止在任何地方传递类型参数

问题描述

我有几个从基类继承的类。它基本上是由包含状态对象的方法返回的结果。

public abstract class ResultBase<TResult, TStatus>
    where TResult : ResultBase<TResult, TStatus>
    where TStatus : ResultStatusBase<TStatus>, new()
{   
    protected ResultBase(TStatus status)
    {
        this.Status = status;
    }

    public TStatus Status { get; internal set; }

    public static TResult ServerUnavailable(string message = "") => _getResult(0, message);

    public static TResult Ok(string message = "") => _getResult(1, message);

    protected static TResult GetResult(int statusValue, string message)
    {
        var status = Enumeration.FromValue<TStatus>(statusValue);
        return (TResult)Activator.CreateInstance(typeof(TResult), status, message);
    }
}


public abstract class ResultStatusBase<T> : Enumeration
    where T : ResultStatusBase<T>, new()
{
    public ResultStatusBase(int value, string displayName)
    {
        this.Value = value;
        this.DisplayName = displayName;
    }

    public int Value { get; protected set; }
    public string DisplayName { get; protected set; }

    public static readonly T Ok = Activator.CreateInstance(typeof(T), 0, "Ok") as T;

    public static readonly T ServerUnavailable = Activator.CreateInstance(typeof(T), 1, "Server Unavailable") as T;
}

这些类可用于创建具体类

public class CreateStatus : ResultStatusBase<CreateStatus> 
{
    public static readonly CreateStatus AlreadyExists = new CreateStatus(100, "Already exists");
}

public class CreateResult: ResultBase<CreateResult, CreateStatus>
{
    public static CreateResult AlreadyExists(string message = "") => GetResult(100, message);
    // Some stuff specific to a create result
}

到目前为止,一切都很好。ResultBase我可以从ResultStatusBase`创建派生类。

问题

这些结果和状态在整个应用程序中使用。例如,我有一个返回结果的 http 客户端。

在这个 http 客户端中,我必须传入两个类型参数,使用反射来创建实例并获取值并使用字符串来获取字段名称。

internal class MyHttpClient<TResult, TStatus>
    where TResult : ResultBase<TResult, TStatus>, new()
    where TStatus : ResultStatusBase<TStatus>, new()
{
    public static GetOkResult()
    {
        return this.GetResult(
            status: this._getStatusFieldValue("Ok"),
            message: "It's Ok");
    )

    public TResult GetResult(TStatus status, string message)
    {
        var result = new TResult();

        return new TResult
        {
            Status = status
        };
    }

    private TStatus _getStatusFieldValue(string fieldName) =>
        typeof(TStatus)
            .GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)
            ?.GetValue(null) as TStatus;
}

问题

这一切都开始让人觉得我的申请中长了一个疣,但我不知道如何通过这个。谁能帮我设计一个更好的设计?

标签: c#generics

解决方案


推荐阅读