首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >层次对象的泛型类工厂或方法

层次对象的泛型类工厂或方法
EN

Stack Overflow用户
提问于 2020-02-06 21:05:38
回答 2查看 76关注 0票数 2

我有层次类和泛型类:

代码语言:javascript
复制
       public class Form
       {
           public string Name { get; set; }
           public string Producer { get; set; }
       }

       public class Book : Form
       {
           public string Topic { get; set; }
           public string Autor { get; set; }
       }

       public class Copybook : Form
       {
           public string Topic { get; set; }
           public int CountPages { get; set; }
       }

       public class Notebook : Form
       {
           public int Cost { get; set; }
       }

       public class Request<T> where T : Form
       {
           public T Form { get; set; }
       }

我想要创建工厂或方法,它将根据逻辑和params创建泛型类的对象。它是怎么制造的?我试过这样做,但是代码不起作用:

代码语言:javascript
复制
        public enum FormParams
        {
            Book,
            Copybook,
            Notebook
        }

        public static class RequestFactory
        {
            public static Request<Form> Create(FormParams formParams)
            {
                if (formParams == FormParams.Book)
                {
                    return new Request<Book>();
                }

                if (formParams == FormParams.Copybook)
                {
                    return new Request<Copybook>();
                }

                return new Request<Notebook>();
            }
        }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-06 21:22:28

您需要向层次结构中添加一个接口,以便将泛型参数标记为协变量。

代码语言:javascript
复制
public class Request<T> : IRequest<T> where T : Form
{
    public T Form { get; set; }
}

public interface IRequest<out T> 
{
    public T Form
    {
        get;
    }
}

然后,需要将Create方法的返回类型更改为IRequest<Form>

代码语言:javascript
复制
public static class RequestFactory
{
    public static IRequest<Form> Create(FormParams formParams)
    {

        if (formParams == FormParams.Book)
        {
            return new Request<Book>();
        }

        if (formParams == FormParams.Copybook)
        {
            return new Request<Copybook>();
        }

        return new Request<Notebook>();
    } 
}
票数 1
EN

Stack Overflow用户

发布于 2020-02-06 21:17:53

如果你仔细考虑的话,你想要的东西根本就没有意义。如果是你干的呢?

代码语言:javascript
复制
var request = RequestFactory.Create(FormParams.CopyBook);
request.Form = new Book();

如果底层的request类型是Request<CopyBook>,那么它的Form属性将具有CopyBook类型,并且尝试将其值设置为Book是没有意义的。

如果您确定上述用例永远不会发生,您可以通过使用不允许设置interface属性的Form来形式化这一事实。然后,您可以使该接口。

代码语言:javascript
复制
public class Request<T> : IRequest<T>
    where T : Form
{
    public T Form { get; set; }
}

public interface IRequest<out T> where T : Form
{
    T Form { get; }
}

...
    public static IRequest<Form> Create(FormParams formParams)

但在这种情况下,您可能会发现没有理由让IRequest是泛型的。

代码语言:javascript
复制
public class Request<T> : IRequest
    where T : Form
{
    public T Form { get; set; }

    Form IRequest.Form => this.Form;
}

public interface IRequest
{
    Form Form { get; }
}

...
    public static IRequest Create(FormParams formParams)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60103509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档