C# T:new()约束并使用默认构造函数(对您来说似乎不够好) 使用反射。很少是最好的主意 指定创建者函数
像这样:C# T:new()约束并使用默认构造函数(对您来说似乎不够好) 使用反射。很少是最好的主意 指定创建者函数,c#,generics,C#,Generics,像这样: public static List<T> GetQueryResult<T>(string xpathQuery) { List<T> lst = new List<T>(); // do stuff return lst; } List<SomeType> items = SomeClass.GetQueryResult<SomeType
public static List<T> GetQueryResult<T>(string xpathQuery)
{
List<T> lst = new List<T>();
// do stuff
return lst;
}
List<SomeType> items = SomeClass.GetQueryResult<SomeType>("query");
public static List<T> GetQueryResults<T>(string xpathQuery, Func<int, T> creator) {
var result = new List<T>();
foreach (i in something)
result.add(creator(i));
return result;
}
公共静态列表GetQueryResults(字符串xpathQuery,Func创建者){
var result=新列表();
foreach(我在某物中)
结果。添加(创建者(i));
返回结果;
}
然后像这样调用它:
List<int> l = GetQueryResults("something", i => new MyObject(i));
List l=GetQueryResults(“某物”,i=>newmyobject(i));
公共静态列表GetQueryResult(字符串xpathQuery){
List lst=新列表();
返回lst;
}
如果您想要静态键入,这是唯一的方法。否则你可以
public static IList GetQueryResults(string xpathQuery, Type itemType) {
Type tp = typeof(List<>).MakeGenericType(itemType);
IList lst = (IList)Activator.CreateInstance(tp);
return lst;
}
公共静态IList GetQueryResults(字符串xpathQuery,类型itemType){
类型tp=typeof(列表)。MakeGenericType(itemType);
IList lst=(IList)Activator.CreateInstance(tp);
返回lst;
}
但在这种情况下,使用非通用列表可能会更好
编辑:您在同一帖子中问了另一个问题:
创建泛型类型实例的3种方法是
public static List<T> GetQueryResult<T>(string xpathQuery)
{
List<T> lst = new List<T>();
// do stuff
return lst;
}
List<SomeType> items = SomeClass.GetQueryResult<SomeType>("query");
public static List<T> GetQueryResults<T>(string xpathQuery, Func<int, T> creator) {
var result = new List<T>();
foreach (i in something)
result.add(creator(i));
return result;
}
公共静态列表GetQueryResults(字符串xpathQuery,Func创建者){
var result=新列表();
foreach(我在某物中)
结果。添加(创建者(i));
返回结果;
}
然后像这样调用它:
List<int> l = GetQueryResults("something", i => new MyObject(i));
List l=GetQueryResults(“某物”,i=>newmyobject(i));
更新问题的答案:
public List<T> GetQueryResult<T>(string xPathQuery)
{
var items = ;// logic to get items
var list = new List<T>();
foreach (Sitecore.Data.Items.Item item in items)
{
list.Add((T) Activator.CreateInstance(typeof(T), item));
}
return list;
}
公共列表GetQueryResult(字符串xPathQuery)
{
var items=;//获取项的逻辑
var list=新列表();
foreach(Sitecore.Data.Items.Item-in-Items)
{
添加((T)Activator.CreateInstance(typeof(T),item));
}
退货清单;
}
我假设T有一个获取Sitecore.Data.Items.Item的构造函数,如果没有,代码将在运行时失败
必须有一种更安全的方法来解决这个问题,如果你能为这个问题提供更广泛的背景就会更好。更新后的问题的答案:
public List<T> GetQueryResult<T>(string xPathQuery)
{
var items = ;// logic to get items
var list = new List<T>();
foreach (Sitecore.Data.Items.Item item in items)
{
list.Add((T) Activator.CreateInstance(typeof(T), item));
}
return list;
}
公共列表GetQueryResult(字符串xPathQuery)
{
var items=;//获取项的逻辑
var list=新列表();
foreach(Sitecore.Data.Items.Item-in-Items)
{
添加((T)Activator.CreateInstance(typeof(T),item));
}
退货清单;
}
我假设T有一个获取Sitecore.Data.Items.Item的构造函数,如果没有,代码将在运行时失败
必须有一种更安全的方法来解决这个问题,如果你能为这个问题提供更广泛的背景,那就更好了。正如其他人所证明的,解决任何
T
的更新问题的唯一方法就是反思。但是,如果T
仅限于一组您可以修改的已知类型,则可以执行以下操作:
public interface IItemContainer
{
void SetItem(Sitecore.Data.Items.Item item);
}
public static List<T> GetQueryResult<T>(string xpathQuery)
where T : IItemContainer, new() {
IList<Sitecore.Data.Items.Item> items = GetAListOfItemsSomehow(xpathQuery);
List<T> result = new List<T>();
foreach (Sitecore.Data.Items.Item item in items) {
T obj = new T();
obj.SetItem(item);
result.add(obj);
}
return result;
}
公共接口IItemContainer
{
作废集合项(Sitecore.Data.Items.Item);
}
公共静态列表GetQueryResult(字符串xpathQuery)
其中T:IItemContainer,new(){
IList items=GetAListOfItemsSomehow(xpathQuery);
列表结果=新列表();
foreach(Sitecore.Data.Items.Item-in-Items){
T obj=新的T();
对象设置项(项);
结果:添加(obj);
}
返回结果;
}
然后,您要用于
T
的任何类型都必须实现IItemContainer
,正如其他人所演示的,解决任何T
的更新问题的唯一方法是使用反射。但是,如果T
仅限于一组您可以修改的已知类型,则可以执行以下操作:
public interface IItemContainer
{
void SetItem(Sitecore.Data.Items.Item item);
}
public static List<T> GetQueryResult<T>(string xpathQuery)
where T : IItemContainer, new() {
IList<Sitecore.Data.Items.Item> items = GetAListOfItemsSomehow(xpathQuery);
List<T> result = new List<T>();
foreach (Sitecore.Data.Items.Item item in items) {
T obj = new T();
obj.SetItem(item);
result.add(obj);
}
return result;
}
公共接口IItemContainer
{
作废集合项(Sitecore.Data.Items.Item);
}
公共静态列表GetQueryResult(字符串xpathQuery)
其中T:IItemContainer,new(){
IList items=GetAListOfItemsSomehow(xpathQuery);
列表结果=新列表();
foreach(Sitecore.Data.Items.Item-in-Items){
T obj=新的T();
对象设置项(项);
结果:添加(obj);
}
返回结果;
}
您想要用于
T
的任何类型都必须实现IItemContainer
我有一种印象,OP在编译时不知道类型,在这种情况下,这不会有帮助…我有一种印象,OP在编译时不知道类型,在这种情况下,这不会有任何帮助…没有理由经历所有这些麻烦…泛型类型被传入并可以直接使用,正如其他帖子中所引用的。-1虽然可以单独使用,但不能在GetQueryResult方法中插入该代码段,因为genericList的编译时类型是object,而不是List。给定签名后,GetQueryResult方法无法编译,您的答案也无法更改。没有理由经历所有这些麻烦…泛型类型已传入,可以直接使用,如其他帖子中所引用。-1虽然可以单独使用,但您不能在GetQueryResult方法中插入该代码段,因为genericList的编译时类型是object,而不是List。给定签名后,GetQueryResult方法不会编译,您的答案也无法更改。基本上,我们想创建一个泛型类型的新对象t
您是否假设t是某个基类,因为它具有特定的构造函数签名?是的。我想创建一个该类型的新对象,并用一些特定的数据填充该对象。在我的例子中,Item i
您的更新显著改变了感知到的问题。根据我在StackOverflow问答动态方面的经验,我想说,如果你问一个全新的问题,你会有更好的机会得到答案。记住:它是免费的:)你不能用基类的名称替换t吗?基本上,我们想创建一个新的泛型对象t
你是否假设t是某个基类,s
List<int> l = GetQueryResults("something", i => new MyObject(i));
public List<T> GetQueryResult<T>(string xPathQuery)
{
var items = ;// logic to get items
var list = new List<T>();
foreach (Sitecore.Data.Items.Item item in items)
{
list.Add((T) Activator.CreateInstance(typeof(T), item));
}
return list;
}
public interface IItemContainer
{
void SetItem(Sitecore.Data.Items.Item item);
}
public static List<T> GetQueryResult<T>(string xpathQuery)
where T : IItemContainer, new() {
IList<Sitecore.Data.Items.Item> items = GetAListOfItemsSomehow(xpathQuery);
List<T> result = new List<T>();
foreach (Sitecore.Data.Items.Item item in items) {
T obj = new T();
obj.SetItem(item);
result.add(obj);
}
return result;
}