C#泛型的问题 - newing了泛型类型的构造函数的参数 [英] C# generics problem - newing up the generic type with parameters in the constructor
问题描述
我试图创建一个通用类新的了泛型类型的实例。具体如下:
I am trying to create a generic class which new's up an instance of the generic type. As follows:
public class HomepageCarousel<T> : List<T>
where T: IHomepageCarouselItem, new()
{
private List<T> GetInitialCarouselData()
{
List<T> carouselItems = new List<T>();
if (jewellerHomepages != null)
{
foreach (PageData pageData in jewellerHomepages)
{
T item = new T(pageData); // this line wont compile
carouselItems.Add(item);
}
}
return carouselItems;
}
}
不过,我得到以下错误:
But I get the following error:
不能创建变量的实例时提供的参数
键入的
cannot provide arguments when creating an instance of a variable type
我发现了以下相关的问题,这是非常接近我所需要的:
<一href=\"http://stackoverflow.com/questions/840261/c-generic-new-constructor-problem/1681770#1681770\">http://stackoverflow.com/questions/840261/c-generic-new-constructor-problem/1681770#1681770
I found the following related question which is very close to what I need: http://stackoverflow.com/questions/840261/c-generic-new-constructor-problem/1681770#1681770
不过,我不能用Jared的建议答案我
调用泛型类中的方法,而不是外界的
,所以我不能指定具体类。
However, I can't used Jared's suggested answer as I am calling the method within the Generic class, not outside of it, so I can't specify the concrete class.
有没有办法解决?
我曾尝试根据其他问题的下面,但
这是行不通的,因为我不知道具体的类型T的
指定。由于它是从通用类里面,不叫
外:
I have tried the following based on the other question, but it doesn't work as I don't know the concrete type of T to specify. As it is called from inside the generic class, not outside:
public class HomepageCarousel<T> : List<T>
where T: IHomepageCarouselItem, new()
{
private List<T> LoadCarouselItems()
{
if (IsCarouselConfigued)
{
return GetConfiguredCarouselData();
}
// ****** I don't know the concrete class for the following line,
// so how can it be instansiated correctly?
return GetInitialCarouselData(l => new T(l));
}
private List<T> GetInitialCarouselData(Func<PageData, T> del)
{
List<T> carouselItems = new List<T>();
if (jewellerHomepages != null)
{
foreach (PageData pageData in jewellerHomepages)
{
T item = del(pageData);
carouselItems.Add(item);
}
}
return carouselItems;
}
}
**** 修改:增加了可能的解决方案**
****EDIT : ADDED POSSIBLE SOLUTIONS**
所以,我已经测试了2可能的解决方案:
So I have tested 2 possible solutions:
首先是完全按照低于乔恩斯基特解释。这个
绝对有效,但指具有在一个不起眼的lambda
构造函数。我不是很舒服的这个,因为它意味着
用户需要知道预期正确的lambda。
毕竟,他们能够通过一个lambda这不新了
类型,但做了完全出乎意料的。
First is exactly as explained below by Jon Skeet. This definitely works but means having an obscure lambda in the constructor. I am not very comfortable with this as it means users need to know the correct lambda that is expected. After all, they could pass a lambda which doesn't new up the type, but does something entirely unexpected
其次,我去了工厂方法途径;
我添加了一个到通用接口创建方式:
Secondly, I went down the Factory method route; I added a Create method to the common interface:
IJewellerHomepageCarouselItem Create(PageData pageData);
然后在每个具体的类提供了一个实现:
Then provided an implementation in each Concrete class:
public IJewellerHomepageCarouselItem Create(PageData pageData)
{
return new JewellerHomepageCarouselItem(pageData, null);
}
和使用两个步骤的初始化语法:
And used a two step initialisation syntax:
T carouselItem = new T();
T homepageMgmtCarouselItem = (T) carouselItem.Create(jewellerPage);
很想听听你对每种方法的优点的一些反馈。
Would love to hear some feedback on the merit of each of these approaches.
推荐答案
Jared的回答仍然是一个很好的路要走 - 你只需要做出的构造采取 Func键&LT; PageData,T&GT;
并藏匿起来以备以后:
Jared's answer is still a good way to go - you just need to make the constructor take the Func<PageData, T>
and stash it for later:
public class HomepageCarousel<T> : List<T> where T: IHomepageCarouselItem
{
private readonly Func<PageData, T> factory;
public HomepageCarousel(Func<PageData, T> factory)
{
this.factory = factory;
}
private List<T> GetInitialCarouselData()
{
List<T> carouselItems = new List<T>();
if (jewellerHomepages != null)
{
foreach (PageData pageData in jewellerHomepages)
{
T homepageMgmtCarouselItem = factory(pageData);
carouselItems.Add(homepageMgmtCarouselItem);
}
}
return carouselItems;
}
然后你只传递给函数到您创建的新实例构造函数中的 HomepageCarousel&LT; T&GT;
(我建议组成,而不是继承,顺便说一句......从导出列表&LT; T&GT;
几乎总是错的路要走。)
(I'd recommend composition instead of inheritance, btw... deriving from List<T>
is almost always the wrong way to go.)
这篇关于C#泛型的问题 - newing了泛型类型的构造函数的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!