[英]Generic class factory or method of hierarchy objects
I have hierarchy class and generic class:我有层次结构类和泛型类:
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; }
}
I want to make factory or method, which will create objects of generic class in depend of logic and params.我想制作工厂或方法,它将根据逻辑和参数创建通用类的对象。 How it make?
它是如何制作的? I tried to do this, but the code did not work:
我试图这样做,但代码不起作用:
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>();
}
}
If you think carefully, what you're asking for doesn't really make sense.如果你仔细想想,你所要求的并不真正有意义。 What if you did this?
如果你这样做了怎么办?
var request = RequestFactory.Create(FormParams.CopyBook);
request.Form = new Book();
If the underlying type of request
was Request<CopyBook>
, then its Form
property would have the type of CopyBook
, and trying to set its value to a Book
wouldn't make sense.如果
request
的基础类型是Request<CopyBook>
,那么它的Form
属性将具有CopyBook
的类型,并且尝试将其值设置为Book
没有意义。
If you determine that the above use-case should never happen, you can formalize that fact by using an interface
that doesn't allow the Form
property to be set.如果您确定上述用例永远不会发生,您可以通过使用不允许设置
Form
属性的interface
来形式化该事实。 Then you can make that interface covariant .然后您可以使该接口covariant 。
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)
But in that case you may find there's no reason to have IRequest
be generic at all.但在这种情况下,您可能会发现根本没有理由让
IRequest
是通用的。
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)
You need to add an Interface to your hierarchy so you can flag the generic parameter as covariant.您需要向层次结构添加一个接口,以便可以将通用参数标记为协变。
public class Request<T> : IRequest<T> where T : Form
{
public T Form { get; set; }
}
public interface IRequest<out T>
{
public T Form
{
get;
}
}
And then you need to change the return type of your Create
method to an IRequest<Form>
.然后您需要将
Create
方法的返回类型更改为IRequest<Form>
。
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>();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.