Question

I am developing a tool to automate some tasks on MSProject using .NET and the Office.MSProject.Interop library.

Suppose I have something like that:

Project actvProject;
var taskInfoDic = actvProject.Tasks.Cast<Task>().Select(
            task => new
            {
                task.Guid,
                task.Name,
                task.Work,
                task.ActualWork,
                task.PercentWorkComplete,
                task.Start,
                task.Finish,
                task.Duration,
                task.Deadline
            }).ToDictionary(x => x.Guid);

 // More code that mutates actvProject and its Task members

Is it possible for the taskInfoDic values (which are made of members of a member of the actvProject object) to be changed if I mutate actvProject ?

Shouldn't an anonymous type value be immutable ??

Was it helpful?

Solution

You can mutate the dictionary, as dictionaries are mutable. This means you can add an entirely new key/value pair, or change the value associated with a key. You can't mutate the existing value object that some key points to (in this case, because the dictionaries value is an immutable type).

You are also copying all of the data out of the original data source when creating the dictionary, you are not copying references to any of the values, or deferring execution in any way, so there are no changes that could be made to the source data structure that could be observed in the new dictionary.

Shouldn't a anonymous type value be immutable?

They are. That doesn't mean that any data structure you put them in is also immutable though.

You could use an IReadOnlyDictionary if you want to ensure the dictionary isn't mutated, but given the fact that you're using an anonymous type, you shouldn't be using this dictionary outside of the scope of the current method; given that, you really shouldn't need to go to such lengths to prevent mutation of the dictionary, as you are the only one who should be able to mutate it.

OTHER TIPS

Is it possible for the taskInfoDic values (which are made of members of a member of the actvProject object) to be changed if I mutate actvProject ?

No, because all of the members you pull out are value types. If any had been reference types than all you have is a reference, and changes to the underlying instances would be reflected in the results of your query.

Shouldn't a anonymous type value be immutable ??

Yes they should, and they are. However, you are creating a dictionary where the anonymous type is the value. Dictionaries are mutable, but the values (in this case) are not.

Here's a rough example that shows once you populate an anonymous type, it's data cannot be changed implicitly:

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

public class Program
{
    static void Main(string[] args)
    {
        var actvProject = new Project();

        var taskInfoDic = actvProject.Tasks.Cast<Task>().Select(
        task => new
        {
            task.Guid,
            task.Name
        }).ToDictionary(x => x.Guid);

        actvProject.Tasks[0].Name = "New Task";

        foreach (var t in taskInfoDic)
        {
            Console.WriteLine(t.Value.Name);    // Still "Task 1"
        }

        // This won't compile as "Name" is readonly.
        // taskInfoDic.ElementAt(0).Value.Name = "test";
    }
}

public class Project
{
    public Project()
    {
        Tasks = new List<Task> { new Task { Name = "Task 1" } };
    }

    public IList<Task> Tasks { get; set; }
}

public class Task
{
    public Guid Guid { get; set; }

    public string Name { get; set; }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top