【问题标题】:How to get around the fact C# doesn't allow void as a generic parameter?如何绕过 C# 不允许 void 作为泛型参数的事实?
【发布时间】:2011-06-29 01:47:23
【问题描述】:

我有以下通用类,它们处理返回不同类型对象的请求:

class Request<T> {
    /* ... */

    public T Result { get; protected set; }
    public abstract bool Execute();
    protected bool ExecuteCore(params /* ... */) { /* ... */ }
}

class ObjectRequest<T> : Request<T>
    where T : class, new() { /* ... */ }

class ListRequest<T> : Request<List<T>>
    where T : class, new() { /* ... */ }

class CompoundRequest<T, U> : Request<T>
    where T : class, IHeader<U>, new()
    where U : class, new() { /* ... */ }

class CompoundRequest<T, U, V> : Request<T>
    where T : class, IHeader<U>, IHeader<V>, IHeader<W>, new()
    where U : class, new()
    where V : class, new() { /* ... */ }

class CompoundRequest<T, U, V, W> : Request<T>
    where T : class, IHeader<U>, IHeader<V>, new()
    where U : class, new()
    where V : class, new()
    where W : class, new() { /* ... */ }

interface IHeader<T> {
    List<T> Details { get; set; }
}

现在我想创建一个类来处理返回 no 对象的请求。但是,不允许将泛型参数设置为 null:

class NoReturnRequest : Request<void> { /* ... */ } // illegal

我该如何解决这个问题?

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    我建议您翻转您的设计模式;首先,您应该构建一个不返回任何内容的非泛型 Request 类,并且它继承泛型 Request&lt;T&gt;Request&lt;T1, T2&gt;Request&lt;T1, T2, T3&gt; 等。确实返回的类价值观。

    【讨论】:

    • @Adam:这违反了里氏替换原则。
    • @Eduardo 我不得不恭敬地不同意。是什么让你这么想?
    • @Adam:这不是我的问题,但如果我遵循你的方法,它会遵循我的课程的实施方式。要么它破坏了 LSP,要么有一些功能需要实现两次。
    • @Eduardo 再说一次,我不同意。虽然我当然不会声称知道你的Request 和相关类的内部细节,但我不确定你为什么不能在非泛型请求类中实现提交请求的细节,以及获取泛型派生类中的返回值。特别是如果您在基类中添加一些虚函数以允许派生类轻松绑定到已经提供的功能。
    • @Adam:对不起,我不明白你在说什么。根据您的建议,将有 两个 基类。 Request 将是 Request&lt;T&gt; 的基础,而 ObjectRequest&lt;T&gt;ListRequest&lt;T&gt;CompoundRequest&lt;T,U&gt;CompoundRequest&lt;T,U,V&gt;CompoundRequest&lt;T,U,V,W&gt; 的基础。你说的是哪个基类?
    【解决方案2】:

    随着 C# 等语言变得更加面向功能,这是一个常见问题。

    Rx 团队通过引入Unit 解决了这个问题。

    【讨论】:

      【解决方案3】:

      泛型用于类型化参数。如果参数没有类型,请使用另一个类的接口或抽象(您的请求也将从该类继承)

      【讨论】:

        猜你喜欢
        • 2020-04-11
        • 1970-01-01
        • 2015-03-29
        • 1970-01-01
        • 2012-01-27
        • 1970-01-01
        • 2010-11-01
        相关资源
        最近更新 更多