2013-12-23 57 views
0

我正在開發一個工具,使用.NET和Office.MSProject.Interop庫自動執行MSProject上的一些任務。在C#匿名類型成員中是否可以使用別名?

假設我有類似的東西:

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 

是否有可能爲taskInfoDic值(由該actvProject對象的成員的成員),如果我發生變異actvProject改變?

不應該匿名類型的值是不可變的?

+3

匿名類型成員是隻讀的。你爲什麼不把它推廣到適當的課堂?這將給你任何你想要的控制... –

回答

2

可以變異的字典,因爲字典是可變的。這意味着您可以添加全新的鍵/值對,或更改與鍵關聯的值。你不能改變現有值對象的某些關鍵點(在這種情況下,因爲字典值是不可變的類型)。

您也在創建字典時複製了原始數據源中的所有數據,不復制對任何值的引用或以任何方式推遲執行,因此沒有可以進行的更改到可以在新字典中觀察到的源數據結構。

匿名類型值不應該是不可變的嗎?

他們是。這並不意味着你放入它們的任何數據結構也是不可變的。

如果你想確保字典不被突變你可以使用一個IReadOnlyDictionary,但鑑於您使用的是匿名類型,你不應使用的範圍之外的這本字典現行方法;考慮到這一點,你真的不需要爲了防止字典的變化而花費這麼長的時間,因爲你是唯一能夠改變它的人。

+0

我的關注是,當我在activProject上工作時,「任務」(在activProject對象中)屬性被改變。我擔心activProject中的這些更改是否能夠將自己反映到字典的值中。 activProject是一個巨大的COM對象,當我完成我的工作時,會產生很多副作用。 現在我的理解是,我無法更改匿名對象內的引用值。但是如果被引用的對象改變它的狀態,這個改變是否會反映在字典返回的值中? –

+0

我認爲我沒有完全正確的術語=( –

+0

@RananRanelli正如我在第二段中所述,在您創建的字典中不能更改源數據結構或其項目,或者它的項目,也就是說,除非你已經取出的'task'的屬性是可變引用類型,否則你需要做一個更深層的副本。 – Servy

0

這裏有一個粗略的例子,顯示了完成填充匿名類型,它的數據不能隱改變:

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; } 
} 
1

是否有可能用於taskInfoDic值(其由與actvProject對象的成員的成員),如果我突變actvProject改變?

不,因爲您拉出的所有成員都是值類型。如果有任何引用類型比你所擁有的是一個引用,並且對底層實例的更改將反映在你的查詢結果中。

不應該匿名類型的值是不可變的?

是的,他們應該,他們。但是,您正在創建字典,其中匿名類型是。字典是可變的,但值(在這種情況下)不是。

+0

我認爲匿名類型是引用類型,而不是值類型 – Servy

+0

@Servy我指的是從原始'任務'列表中刪除的字段 - 'Guid','Name'等。 –

相關問題