Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# T:new()约束并使用默认构造函数(对您来说似乎不够好) 使用反射。很少是最好的主意 指定创建者函数_C#_Generics - Fatal编程技术网

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种方法是

  • 使用where T:new()约束并使用默认构造函数(对您来说似乎不够好)
  • 使用反射。很少是最好的主意
  • 指定创建者函数
  • 像这样:

        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;
    }