Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# How can I tell if an IEnumerable is Mutable?

I want a method to update certain entries of an IEnumerable. I found that doing a foreach over the entries and updating the values failed as in the background I was cloning the collection. This was because my IEnumerable was backed by some LINQ->SQL queries.

By changing the method to take a List I have changed this behavior, Lists are always mutable and hence the method changes the actual objects in the list. Rather than demand a List is passed is there a Mutable interface I can use?

    // Will not behave as consistently for all IEnumerables
    public void UpdateYesterday (IEnumerable<Job> jobs) {
          foreach (var job in jobs.Where(x => x.date == Yesterday)) {
             job.done = true;
          }
    }

    ...

    public class Job {  
         ...           
         public DateTime Date { get; set; }
    }
like image 798
Logan Avatar asked May 18 '10 09:05

Logan


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.


2 Answers

You're not changing the list at all here - the collection itself could be immutable and this code would still "work". You're changing the data within the items in the collection.

Imagine a row of houses - that's pretty immutable (creating or destroying a house is tricky) but you can still change the contents of those houses.

So, what you really need to know is whether the elements of the collection are going to be cloned or not... whether you'll get a collection of "new" jobs each time you perform the query, or whether it'll use the existing objects.

like image 61
Jon Skeet Avatar answered Sep 21 '22 20:09

Jon Skeet


Here's one hypothetical way this might happen. Say you have a method that takes an existing data source and creates Job objects from that source.

Something like this:

public IEnumerable<Job> GetJobs() {
    var rows = GetRowsFromDatabaseTable();

    foreach (var row in rows)
        yield return new Job(row.Name, row.Date, row.Etc);
}

Then if you had code that did this:

var jobs = GetJobs();

UpdateYesterday(jobs);

foreach (var job in jobs)
    Console.WriteLine(job);

You would find that the jobs you printed using Console.WriteLine did not reflect the updates you performed in UpdateYesterday. This is because UpdateYesterday would have enumerated over the new objects created by GetJobs, and then your foreach loop would have enumerated over a new set of new objects created (again) by GetJobs.

On the other hand, if you simply changed that first line to this:

var jobs = GetJobs().ToList();

Then you would have put all those new objects created by GetJobs into a list, where they would persist, and thus your UpdateYesterday and foreach loop would be referring to the same objects (the ones in the list you created).

Does that make sense? I think this could very well be the problem you're encountering (in which case, the answer is indeed to construct a collection such as a List<Job> in memory from which you can access members to manipulate).

In answer to your question about being able to tell if an IEnumerable is mutable or not, though... well, I really don't think that is possible.

I've removed the old answer, as the new one seems to be what the OP needed.

like image 33
Dan Tao Avatar answered Sep 20 '22 20:09

Dan Tao