c# - 如何使 IEnumerable<T> 只读?

标签 c# .net generics ienumerable

为什么下面代码的Main方法中的列表list1Instancep指向同一个集合?

class Person
    {
        public string FirstName = string.Empty;
        public string LastName = string.Empty;

        public Person(string firstName, string lastName) {
            this.FirstName = firstName;
            this.LastName = lastName;
        }
    }

    class List1
    {
        public List<Person> l1 = new List<Person>();

        public List1()
        {
            l1.Add(new Person("f1","l1"));
            l1.Add(new Person("f2", "l2"));
            l1.Add(new Person("f3", "l3"));
            l1.Add(new Person("f4", "l4"));
            l1.Add(new Person("f5", "l5"));
        }
        public IEnumerable<Person> Get()
        {
            foreach (Person p in l1)
            {
                yield return p;
            }

            //return l1.AsReadOnly(); 
        }

    }  

    class Program
    {

        static void Main(string[] args)
        {
            List1 list1Instance = new List1();

            List<Person> p = new List<Person>(list1Instance.Get());           

            UpdatePersons(p);

            bool sameFirstName = (list1Instance.l1[0].FirstName == p[0].FirstName);
        }

        private static void UpdatePersons(List<Person> list)
        {
            list[0].FirstName = "uf1";
        }
    }

我们能否在不更改 List1.Get() 的返回类型的情况下更改此行为?

谢谢

最佳答案

事实上,IEnumerable<T> 已经是只读的。这意味着您不能用不同的项目替换基础集合中的任何项目。也就是说,您不能更改对 Person引用集合中保存的对象。类型Person但是,它不是只读的,因为它是引用类型(即 class ),您可以通过引用更改其成员。

有两种解决方法:

  • 使用 struct作为返回类型(每次返回时都会复制该值,因此不会更改原始值——顺便说一句,这可能代价高昂)
  • Person 上使用只读属性键入以完成此任务。

关于c# - 如何使 IEnumerable<T> 只读?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/359495/

相关文章:

.net - 在嵌入式linux中使用mono作为硬件

c# - 使用字典和泛型创建嵌套的 JSON 可序列化对象结构时,.NET 中的 C# 协方差存在问题

c# - 如何阻止 JIT 调试器介入崩溃的 wcf 服务?

c# - 选择一组二进制序列以避免相似性

c# - 带三个大括号的内插字符串

C# mysql 一键更新和选择

.net - 在 SQL Server 2005 存储过程中使用 .NET Framework 3.5

java - 调用其参数受交集类型限制的方法

swift - 如何使用 Swift 中的 where 检查/将类转换为泛型类型

c# - 标准处理模式?为什么我们在虚拟方法中需要 "disposing"参数,并且终结器不是总是在处理后调用?