لماذا تعيين خاصية على تعداد وجوه لا تعمل؟

StackOverflow https://stackoverflow.com/questions/317527

  •  11-07-2019
  •  | 
  •  

سؤال

وأنا أعرف الكثير عن C # ولكن هذا واحد هو التعكز لي وجوجل لا يساعد.

ولدي مجموعة IEnumerable من الكائنات. أريد أن تعيين خاصية على أول واحد. وأنا أفعل ذلك، ولكن عندما تعداد على مجموعة من الأشياء بعد التعديل، وأنا لا أرى بلدي التغيير.

وهنا مثال جيد لهذه المشكلة:

    public static void GenericCollectionModifier()
    {
        // 1, 2, 3, 4... 10
        var range = Enumerable.Range(1, 10);

        // Convert range into SubItem classes
        var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i});

        Write(items);  // Expect to output 1,2,3,4,5,6,7,8,9,10

        // Make a change
        items.First().MagicNumber = 42;

        Write(items);  // Expect to output 42,2,3,4,5,6,7,8,9,10
        // Actual output: 1,2,3,4,5,6,7,8,9,10
    }

    public static void Write(IEnumerable<SubItem> items)
    {
        Console.WriteLine(string.Join(", ", items.Select(item => item.MagicNumber.ToString()).ToArray()));
    }

    public class SubItem
    {
       public string Name;
       public int MagicNumber;
    }

وماذا جوانب C # توقف بلدي التغيير "MagicNumber = 42" من كونها الإخراج؟ هل هناك طريقة يمكنني الحصول على بلدي التغيير إلى "عصا" دون أن تفعل بعض جبان تحويل إلى قائمة <> أو مجموعة؟

وشكرا! مايك

هل كانت مفيدة؟

المحلول

عند استدعاء الأول () أن يعدد على نتيجة من هذا قليلا من التعليمات البرمجية:

Select(i => new SubItem() {Name = "foo", MagicNumber = i});

لاحظ أن تحديد هو العداد كسول، وهذا يعني أنه لا فقط حدد عندما تسأل عن عنصر من ذلك (ويفعل <م> كل الوقت الذي يطلب منها). لا يتم تخزين النتائج في أي مكان، لذلك عند استدعاء items.First () تحصل على سبيل المثال SubItem الجديد. عند ثم تمرير بنود كتابة، فإنه يحصل على مجموعة كاملة من الحالات SubItem جديدة - وليس واحدة حصلت قبل

إذا كنت تريد تخزين نتيجة اختيار الخاصة بك وتعديله، ما عليك القيام به شيئا مثل:

var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i}).ToList();

نصائح أخرى

وأظن شيء ما يحدث في الخلفية. على الأرجح بسبب حقيقة IEnumerables يمكن كرر مرة واحدة فقط.

هل يعمل إذا قمت بإضافة "ToList () 'بعد استدعاء حدد () عند تعيين لسلع"؟

والشيء الوحيد الذي يمكنني أن أفكر في أن items.First () يمر على نسخة من البند الفرعي لبك بدلا من الإشارة، وذلك عندما قمت بتعيين أنه لم يتم تنفيذ التغيير من خلال.

ولقد لنفترض أن لديها ما تفعله مع IQueryable كونها قادرة على أن تكون كرر مرة واحدة فقط. قد ترغب في محاولة تغيير هذا:

// Convert range into SubItem classes
var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i});

إلى

// Convert range into SubItem classes
var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i}).ToList();

ومعرفة ما إذا كان هناك أي نتائج مختلفة.

وأنت لا يمكن / يجب أن لا تعديل مجموعة من خلال العداد. أنا مندهش هذا لا بطرح استثناء.

و. أولا () هو وسيلة وليس الممتلكات. تقوم بإرجاع مثيل جديد من الكائن في المركز الأول من Enumerable الخاص بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top