c#如何把一list<> 复制到 另一个list<>

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#如何把一list<> 复制到 另一个list<>相关的知识,希望对你有一定的参考价值。

参考技术A 你是要深度赋值还是要浅度赋值,深度赋值要看list里存的对象是什么,然后自己编程轮训list进行赋值。浅度赋值直接类型转换赋值即可,就相当于把指针给它。本回答被提问者和网友采纳 参考技术B

List<DIS_Model.Model_V_SYS_User_Info> list = v_userinfo.select(strWhere, PageSize, PageIndex);

            List<Model_V_SYS_User_Info> students = new List<Model_V_SYS_User_Info>();            for (int i = 0; i < list.Count; i++)                            model=new Model_V_SYS_User_Info();                model.User_Code = list[i].User_Code;                model.User_Email = list[i].User_Email;                model.User_Name = list[i].User_Name;                model.User_Address = list[i].User_Address;                model.ID = list[i].ID;                model.User_Phone = list[i].User_LinPhone;                students.Add(model);            
参考技术C 1、List的基础、常用方法:
声明:
1、List<T> mList = new List<T>();
T为列表中元素类型,现在以string类型作为例子
E.g.:List<string> mList = new List<string>();

2、List<T> testList =new List<T> (IEnumerable<T> collection);
以一个集合作为参数创建List
E.g.:
string[] temArr = "Ha", "Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", "Locu" ;
List<string> testList = new List<string>(temArr);

添加元素:
1、 List. Add(T item) 添加一个元素
E.g.:mList.Add("John");
2、 List. AddRange(IEnumerable<T> collection) 添加一组元素
E.g.:
string[] temArr = "Ha","Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", "Locu" ;
mList.AddRange(temArr);
3、Insert(int index, T item); 在index位置添加一个元素
E.g.:mList.Insert(1, "Hei");
遍历List中元素:
foreach (T element in mList) T的类型与mList声明时一样

Console.WriteLine(element);


E.g.:
foreach (string s in mList)

Console.WriteLine(s);


删除元素:
1、 List. Remove(T item)删除一个值
E.g.:mList.Remove("Hunter");
2、 List. RemoveAt(int index); 删除下标为index的元素
E.g.:mList.RemoveAt(0);
3、 List. RemoveRange(int index, int count);
从下标index开始,删除count个元素
E.g.:mList.RemoveRange(3, 2);
判断某个元素是否在该List中:
List. Contains(T item) 返回true或false,很实用
E.g.:
if (mList.Contains("Hunter"))

Console.WriteLine("There is Hunter in the list");

else

mList.Add("Hunter");
Console.WriteLine("Add Hunter successfully.");


给List里面元素排序:
List. Sort () 默认是元素第一个字母按升序
E.g.:mList.Sort();
给List里面元素顺序反转:
List. Reverse () 可以与List. Sort ()配合使用,达到想要的效果
E.g.:mList.Sort();

List清空:List. Clear ()
E.g.: mList.Clear();
获得List中元素数目:
List. Count () 返回int值
E.g.:
int count = mList.Count();
Console.WriteLine("The num of elements in the list: " +count);

2、List的进阶、强大方法:
举例用的List:
string[] temArr = Ha","Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", " "Locu" ;
mList.AddRange(temArr);

List.Find 方法:搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的第一个匹配元素。
public T Find(Predicate<T> match);
Predicate是对方法的委托,如果传递给它的对象与委托中定义的条件匹配,则该方法返回 true。当前 List 的元素被逐个传递给Predicate委托,并在 List 中向前移动,从第一个元素开始,到最后一个元素结束。当找到匹配项时处理即停止。
Predicate 可以委托给一个函数或者一个拉姆达表达式:
委托给拉姆达表达式:
E.g.:
string listFind = mList.Find(name => //name是变量,代表的是mList
//中元素,自己设定
if (name.Length > 3)

return true;

return false;
);
Console.WriteLine(listFind); //输出是Hunter

委托给一个函数:
E.g.:
string listFind1 = mList.Find(ListFind); //委托给ListFind函数
Console.WriteLine(listFind); //输出是Hunter

ListFind函数:
public bool ListFind(string name)

if (name.Length > 3)

return true;

return false;

这两种方法的结果是一样的。

List.FindLast 方法:搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的最后一个匹配元素。
public T FindLast(Predicate<T> match);
用法与List.Find相同。
List.TrueForAll方法: 确定是否 List 中的每个元素都与指定的谓词所定义的条件相匹配。
public bool TrueForAll(Predicate<T> match);
委托给拉姆达表达式:
E.g.:
bool flag = mList.TrueForAll(name =>

if (name.Length > 3)

return true;

else

return false;


);
Console.WriteLine("True for all: "+flag); //flag值为false
委托给一个函数,这里用到上面的ListFind函数:
E.g.:
bool flag = mList.TrueForAll(ListFind); //委托给ListFind函数
Console.WriteLine("True for all: "+flag); //flag值为false
这两种方法的结果是一样的。

List.FindAll方法:检索与指定谓词所定义的条件相匹配的所有元素。
public List<T> FindAll(Predicate<T> match);
E.g.:
List<string> subList = mList.FindAll(ListFind); //委托给ListFind函数
foreach (string s in subList)

Console.WriteLine("element in subList: "+s);

这时subList存储的就是所有长度大于3的元素

List.Take(n): 获得前n行 返回值为IEnumetable<T>,T的类型与List<T>的类型一样
E.g.:
IEnumerable<string> takeList= mList.Take(5);
foreach (string s in takeList)

Console.WriteLine("element in takeList: " + s);


这时takeList存放的元素就是mList中的前5个

List.Where方法:检索与指定谓词所定义的条件相匹配的所有元素。跟List.FindAll方法类似。
E.g.:
IEnumerable<string> whereList = mList.Where(name =>

if (name.Length > 3)

return true;

else

return false;

);
foreach (string s in subList)

Console.WriteLine("element in subList: "+s);

这时subList存储的就是所有长度大于3的元素

List.RemoveAll方法:移除与指定的谓词所定义的条件相匹配的所有元素。
public int RemoveAll(Predicate<T> match);
E.g.:
mList.RemoveAll(name =>

if (name.Length > 3)

return true;

else

return false;

);
foreach (string s in mList)

Console.WriteLine("element in mList: " + s);

这时mList存储的就是移除长度大于3之后的元素。

List<T> 是一个泛型链表...T表示节点元素类型
比如
List<int> intList;表示一个元素为int的链表
intList.Add(34); //添加
intList.Remove(34);//删除
intList.RemoveAt(0); //删除位于某处的元素
intList.Count; //链表长度
还有Insert,Find,FindAll,Contains等方法,也有索引方法 intList[0] = 23;
1.减少了装箱拆箱
2.便于编译时检查数据类型
List<Object> 就相当于 System.Collections命名空间里面的List

C# 泛型重载 List<T> :这将如何完成?

【中文标题】C# 泛型重载 List<T> :这将如何完成?【英文标题】:C# Generic overloading of List<T> : How would this be done? 【发布时间】:2011-04-19 23:20:42 【问题描述】:

StringBuilder 类允许您以我认为非常直观的方式将方法调用链接到 .Append()、.AppendFormat() 和其他一些类似的方法:

StringBuilder sb = new StringBuilder();
sb.Append("first string")
  .Append("second string);

另一方面,List 类的 .Add() 方法返回 void - 因此链接调用不起作用。在我看来,这和 Jayne Cobb 的不朽话语“完全没有意义”。

我承认我对泛型的理解非常基础,但我想重载 .Add() 方法(和其他方法),以便它们返回原始对象,并允许链接。任何和所有帮助都将获得更多 Firefly 报价。

【问题讨论】:

【参考方案1】:

如果您想为 Add 方法保留相同的名称,您可以从基类中隐藏该方法:

public class MyList<T> : List<T>

    public new MyList<T> Add(T item)
    
        base.Add(item);
        return this;
    

但是,这仅在您使用显式类型为 MyList&lt;T&gt; 的变量操作列表时才有效(例如,如果您的变量被声明为 IList&lt;T&gt;,它将不起作用)。所以我认为涉及扩展方法的解决方案更好,即使这意味着更改方法的名称。

虽然其他人已经发布了带有扩展方法的解决方案,但这里有另一个,它的优点是保留了集合的实际类型:

public static class ExtensionMethods

    public static TCollection Append<TCollection, TItem>(this TCollection collection, TItem item)
        where TCollection : ICollection<TItem>
    
        collection.Add(item);
        return collection;
    

像这样使用它:

var list = new List<string>();
list.Append("Hello").Append("World");

【讨论】:

这是最完整的答案,最先发布 - 它们都非常相似,因此很难选择哪个作为答案。感谢大家的讨论:我学到了很多。【参考方案2】:

使用可以创建扩展方法

public static class ListExtensions

    public static List<T> AddItem<T>(this List<T> self, T item)
    
        self.Add(item);
        return self;
    


var l = new List<int>();
l.AddItem(1).AddItem(2);

编辑

我们也可以通过集合参数使这个方法泛型

public static class ListExtensions
   
    public static TC AddItem<TC, T>(this TC self, T item)
        where TC : ICollection<T>
    
        self.Add(item);
        return self;
    


var c1 = new Collection<int>();
c1.AddItem(1).AddItem(2);

var c2 = new List<int>();
c2.AddItem(10).AddItem(20);

编辑 2: 也许有人会发现这个技巧很有用,可以利用嵌套对象初始化器和集合初始化器来设置属性并将值添加到现有实例中。

using System;
using System.Collections.Generic;
using System.Linq;

struct I<T>

    public readonly T V;
    public I(T v)
    
        V = v;
    


class Obj

    public int A  get; set; 
    public string B  get; set; 

    public override string ToString()
    
        return string.Format("A=0, B=1", A, B);
    



class Program

    static void Main()
    
        var list = new List<int>  100 ;
        new I<List<int>>(list)
            
                V =  1, 2, 3, 4, 5, 6 
            ;

        Console.WriteLine(string.Join(" ", list.Select(x => x.ToString()).ToArray())); // 100 1 2 3 4 5 6 

        var obj = new Obj  A = 10, B = "!!!" ;
        Console.WriteLine(obj); // A=10, B=!!!
        new I<Obj>(obj)
            
                V =  B = "Changed!" 
            ;
        Console.WriteLine(obj); // A=10, B=Changed!
    

【讨论】:

不改方法名有没有办法做到这一点?我想尽量减少其他开发人员可能产生的困惑 您应该将参数声明为 ICollection 而不是 List @Thomas: Add() 是 IList 和 ICollection 的方法 @desco IList 也是如此,这就是为什么我将答案更改为处理并返回 List。 @ScottSEA 如果您可以更改方法的机制但不能更改其名称,那么这真的会让其他开发人员感到困惑。事实上,我已经避免了整个链接方法,因为它在 C# 中不像其他一些语言那样惯用,因此很容易引起混淆(事实上,因为有些人反对链接,因为它可以把人们绊倒到它所在的地方和不允许的地方)。 @abatishchev,是的,但是 IList 继承了 ICollection。您应该尽可能使用派生较少的类型【参考方案3】:
public static IList<T> Anything-not-Add*<T>(this IList<T> list, T item)

    list.Add(item);
    return list;

*AddItemAppendAppendList等(见下方的cmets)

我也像其他人一样独立地想到了同样的想法:

public static TList Anything<TList, TItem>(this TList list, TItem item)
    where TList : IList<TItem>

    list.Add(item);
    return list;

Thomas 是对的:就IList&lt;T&gt; 继承ICollection&lt;T&gt; 而言,您应该使用ICollection。

【讨论】:

取胜的扩展方法!这仅适用于 C# 3 或更高版本(因此 VS 2008 或 2010)。 这不起作用,因为在重载解析期间编译器会更喜欢实例方法而不是扩展 这是一种扩展方法吧?编译器如何知道使用这个版本的方法而不是原来的(@desco 似乎在说它不会)【参考方案4】:

关闭扩展方法:

public static List<T> Append(this List<T> list, T item)

  list.Add(item);
  return self;

请注意,我们必须使用新名称创建它,就好像实例成员与签名匹配(您已经在抱怨的“添加”),然后扩展方法将不会被调用。

不过,我建议不要这样做。虽然我喜欢链接自己,但它在 C# 库中很少见,这意味着它不像在其他更常见的语言中那样惯用(没有技术原因,尽管属性工作方式的一些差异在其他一些语言中鼓励它更多一些) ,就像事情的共同点一样)。因此,它所支持的结构在 C# 中不像在其他地方那样熟悉,而且您的代码更有可能被其他开发人员误读。

【讨论】:

【参考方案5】:

您可以使用不同名称的扩展方法:

public static T Put<T, U>(this T collection, U item) where T : ICollection<U> 
  collection.Add(item);
  return collection;

要创建这样的代码:

var list = new List<int>();
list.Put(1).Put(2).Put(3);

但是,要保留名称Add,您可以使用如下方法:

public static T Add<T, U>(this T collection, Func<U> itemProducer) 
  where T : ICollection<U> 
  collection.Add(itemProducer());
  return collection;

然后创建这样的代码:

list.Add(()=>1).Add(()=>2).Add(()=>3);

虽然看起来不太好。

也许如果我们改变类型,我们可以有更好的语法。

鉴于这个类:

public class ListBuilder<T> 
  IList<T> _list;
  public ListBuilder(IList<T> list) 
    _list = list;
  
  public ListBuilder<T> Add(T item) 
    _list.Add(item);
    return this;
  

你可以有这个方法:

public static ListBuilder<T> Edit<T>(this IList<T> list) 
  return new ListBuilder<T>(list);

并使用这样的代码:

list.Edit().Add(1).Add(2).Add(3);

【讨论】:

【参考方案6】:

我相信您不会欣赏这个答案,但 List.Add() 以这种方式工作是有充分理由的。它非常快,需要与数组竞争,因为它是一种低级方法。然而,它只是一根头发太大而无法被 JIT 优化器内联。它无法优化您需要返回列表引用的 return 语句。

在您的代码中编写 lst.Add(obj) 是免费的,lst 引用在 CPU 寄存器中可用。

返回引用的 Add() 版本使代码慢了近 5%。建议的扩展方法更糟糕,涉及整个额外的堆栈帧。

【讨论】:

我相信你不会欣赏这个评论,但也许你可以解释为什么我不会欣赏这个答案。它写得很好,易于理解,并提出了一些关于优化的要点。【参考方案7】:

我喜欢其他人提到的扩展方法,因为它似乎很好地回答了这个问题(尽管您必须为其提供与现有 Add() 不同的方法签名)。此外,在这样的调用中,对象返回似乎确实存在一些不一致(我认为这是一个可变性问题,但 stringbuilder 是可变的,不是吗?),所以你提出了一个有趣的问题。

不过,我很好奇,AddRange 方法是否不能作为开箱即用的解决方案?您是否有特殊原因要链接命令而不是将所有内容作为数组传递?

做这样的事情不能满足你的需要吗?

List<string> list = new List<string>();
list.AddRange(new string[]
    "first string", 
    "second string",
);

【讨论】:

以上是关于c#如何把一list<> 复制到 另一个list<>的主要内容,如果未能解决你的问题,请参考以下文章

C#泛型列表<T>如何获取T的类型? [复制]

C#中Listview的数据复制到另外一个Listview的问题

C# 中 List<T> 的只读冲突? [复制]

怎么样把一台戴尔服务器装好centos系统复制到另一台服务器上?

C# 中如何从List集合中提取第一个值

C# 是通过引用还是作为副本将 List<T> 传递给方法? [复制]