c# - ToList()-এটি একটি নতুন তালিকা তৈরি করে?




linq (8)

চলো আমি একটি ক্লাস আছে

public class MyObject
{
   public int SimpleInt{get;set;}
}

এবং আমার একটি List<MyObject> , এবং আমি ToList() এবং তারপর একটি SimpleInt পরিবর্তন করি, আমার পরিবর্তনটি মূল তালিকাতে প্রচারিত হবে। অন্য কথায়, নিম্নলিখিত পদ্ধতির আউটপুট কি হবে?

public void RunChangeList()
{
  var objs = new List<MyObject>(){new MyObject(){SimpleInt=0}};
  var whatInt = ChangeToList(objs );
}
public int ChangeToList(List<MyObject> objects)
{
  var objectList = objects.ToList();
  objectList[0].SimpleInt=5;
  return objects[0].SimpleInt;

}

কেন?

পি / এস: এটা খুঁজে বের করতে স্পষ্ট মনে হচ্ছে যদি আমি দুঃখিত। কিন্তু এখন আমার সাথে কম্পাইলার নেই ...

https://code.i-harness.com


ToList সর্বদা একটি নতুন তালিকা তৈরি করবে, যা সংগ্রহের পরবর্তী পরিবর্তনগুলি প্রতিফলিত করবে না।

যাইহোক, এটি বস্তুর পরিবর্তনগুলি প্রতিফলিত করবে (যতক্ষণ না তারা পরিবর্তনযোগ্য structs)।

অন্য কথায়, যদি আপনি কোনও বস্তুর মূল তালিকায় একটি ভিন্ন বস্তুর সাথে প্রতিস্থাপন করেন তবে, তালিকার তালিকায় এখনও প্রথম অবজেক্ট থাকবে।
যাইহোক, যদি আপনি আসল তালিকায় থাকা বস্তুর মধ্যে একটি পরিবর্তন করেন তবে ToList একই (সংশোধিত) অবজেক্ট ধারণ করবে।


আমি ডকুমেন্টেশনের যে কোনও জায়গায় দেখতে পাই না যে ToList () সর্বদা একটি নতুন তালিকা ফেরত দেওয়ার জন্য নিশ্চিত। যদি একটি অণুসংখ্যা একটি তালিকা হয় তবে এটি পরীক্ষা করার জন্য আরও কার্যকর হতে পারে এবং কেবলমাত্র একই তালিকাটি ফেরত পাঠাতে পারে।

উদ্বেগ হল যে কখনও কখনও আপনি সম্পূর্ণ নিশ্চিত হতে পারেন যে প্রত্যাশিত তালিকাটি হল = মূল তালিকাতে! কারণ মাইক্রোসফ্ট নথিভুক্ত করে না যে ToList একটি নতুন তালিকা ফিরিয়ে আনবে, আমরা নিশ্চিত হতে পারছি না (যদি না যে কেউ ডকুমেন্টেশন খুঁজে পায়)। ভবিষ্যতেও এটি পরিবর্তন হতে পারে, এমনকি এটি এখনই কাজ করে।

নতুন তালিকা (IENumerable enumerablestuff) একটি নতুন তালিকা ফিরে নিশ্চিত করা হয়। আমি পরিবর্তে এই ব্যবহার করবে।


একটি নতুন তালিকা তৈরি করা হয়েছে তবে এতে আইটেমগুলি মূল উপাদানগুলিতে (যেমন আসল তালিকাতে রয়েছে) রেফারেন্স। তালিকা নিজেই পরিবর্তন স্বাধীন, কিন্তু আইটেম উভয় তালিকা পরিবর্তন পাবেন।


গৃহীত উত্তর সঠিকভাবে তার উদাহরণের ভিত্তিতে ওপের প্রশ্নটি ঠিক করে। যাইহোক, এটি শুধুমাত্র তখনই প্রয়োগ হয় যখন কংক্রিট সংগ্রহে ToList প্রয়োগ করা হয়; যখন সোর্স ক্রমটির উপাদানগুলি তাত্ক্ষণিক করা হয় না তখন বিলম্বিত হয় না (মুলতুবি কার্যকরকরণের কারণে)। পরবর্তী ক্ষেত্রে, আপনি প্রতিটি সময় যখন আপনি ToList (অথবা ক্রমানুসারে ToList ) কল করেন ToList একটি নতুন সেট আইটেম পেতে পারে।

এই আচরণটি প্রদর্শনের জন্য OP এর কোডটি এখানে একটি অভিযোজন:

public static void RunChangeList()
{
    var objs = Enumerable.Range(0, 10).Select(_ => new MyObject() { SimpleInt = 0 });
    var whatInt = ChangeToList(objs);   // whatInt gets 0
}

public static int ChangeToList(IEnumerable<MyObject> objects)
{
    var objectList = objects.ToList();
    objectList.First().SimpleInt = 5;
    return objects.First().SimpleInt;
}

উপরের কোডটি কুপিত প্রদর্শিত হতে পারে, তবে এই আচরণ অন্যান্য পরিস্থিতিতে একটি সূক্ষ্ম বাগ হিসাবে প্রদর্শিত হতে পারে। এমন একটি পরিস্থিতির জন্য আমার অন্য উদাহরণটি দেখুন যেখানে এটি বারবার ঘুরে বেড়ায়।


যদি উৎস বস্তুটি সত্যিকারের আইনেমেরেবল (অর্থাত্ কেবলমাত্র সংখ্যার হিসাবে একটি প্যাকেজ সংগ্রহ করা না হয়), টলস্ট () আসল আইনেমেরেবলের মতো একই বস্তুর উল্লেখগুলি ফেরত দিতে পারে না। এটি বস্তুগুলির একটি নতুন তালিকা প্রদান করবে, তবে ঐ বস্তুগুলি একই রকম নাও হতে পারে অথবা এমনকি অণুবৃত্তির দ্বারা উত্পাদিত বস্তুর সমান হবে যখন এটি আবার গণনা করা হয়


শুধু এই পুরানো পোস্ট এবং আমার দুই সেন্ট যোগ করার চিন্তা উপর stumble। সাধারণভাবে, যদি আমি সন্দেহ করি তবে সনাক্তকরণগুলি পরীক্ষা করার জন্য আমি দ্রুত কোনও বস্তুতে GetHashCode () পদ্ধতি ব্যবহার করি। তাই উপরের জন্য -

    public class MyObject
{
    public int SimpleInt { get; set; }
}


class Program
{

    public static void RunChangeList()
    {
        var objs = new List<MyObject>() { new MyObject() { SimpleInt = 0 } };
        Console.WriteLine("objs: {0}", objs.GetHashCode());
        Console.WriteLine("objs[0]: {0}", objs[0].GetHashCode());
        var whatInt = ChangeToList(objs);
        Console.WriteLine("whatInt: {0}", whatInt.GetHashCode());
    }

    public static int ChangeToList(List<MyObject> objects)
    {
        Console.WriteLine("objects: {0}", objects.GetHashCode());
        Console.WriteLine("objects[0]: {0}", objects[0].GetHashCode());
        var objectList = objects.ToList();
        Console.WriteLine("objectList: {0}", objectList.GetHashCode());
        Console.WriteLine("objectList[0]: {0}", objectList[0].GetHashCode());
        objectList[0].SimpleInt = 5;
        return objects[0].SimpleInt;

    }

    private static void Main(string[] args)
    {
        RunChangeList();
        Console.ReadLine();
    }

এবং আমার মেশিনে উত্তর -

  • objs: 45653674
  • objs [0]: 41149443
  • বস্তু: 45653674
  • বস্তু [0]: 41149443
  • বস্তু তালিকা: 39785641
  • বস্তু তালিকা [0]: 41149443
  • কি নয়: 5

তাই মূলত তালিকা যে বস্তু বহির্ভূত কোড একই থাকে। প্রত্যাশা সাহায্য করে আশা করি।


ToList একটি ব্র্যান্ড নতুন তালিকা তৈরি করবে।

যদি তালিকার আইটেমগুলি মানগুলির ধরন হয় তবে তারা সরাসরি উল্লেখ করা হবে, যদি তারা রেফারেন্স প্রকার থাকে তবে কোনও পরিবর্তন রেফারেন্সকৃত বস্তুগুলিতে প্রতিফলিত হবে।


হ্যাঁ, এটি একটি নতুন তালিকা তৈরি করে। এই নকশা দ্বারা হয়।

তালিকায় আসল সংখ্যাসূচক ক্রম হিসাবে একই ফলাফল থাকবে, কিন্তু একটি স্থায়ী (ইন মেমরি) সংগ্রহের মধ্যে বস্তুগত। এই আপনি ক্রম recomputing খরচ বহন ছাড়া ফলাফল একাধিক বার গ্রাস করতে পারবেন।

LINQ ক্রম সৌন্দর্য তারা composable হয়। প্রায়শই, IEnumerable<T> আপনি একাধিক ফিল্টারিং, ক্রমানুসার এবং / অথবা অভিক্ষেপ ক্রিয়াকলাপের IEnumerable<T> ফলাফল পাবেন। ToList() এবং ToList() মতো এক্সটেনশন পদ্ধতি আপনাকে গণিত ক্রমানুসারে একটি মান সংগ্রহের রূপান্তর করতে দেয়।





linq