簡體   English   中英

C#匿名類型成員中是否可以使用別名?

[英]Is aliasing possible in C# anonymous type members?

我正在開發一種工具,用於使用.NET和Office.MSProject.Interop庫自動執行MSProject上的某些任務。

假設我有這樣的事情:

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

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

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

創建字典時,您還將所有數據從原始數據源中復制出來,而不是復制對任何值的引用或以任何方式推遲執行,因此無法對源數據進行任何更改。新字典中可以觀察到的結構。

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

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

如果要確保字典不發生突變,可以使用IReadOnlyDictionary ,但是鑒於您使用的是匿名類型,因此不應在當前方法的范圍之外使用此字典。 鑒於此,您真的不需要花那么長時間來防止字典的突變,因為您是唯一應該能夠對其進行突變的人。

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

不,因為您拉出的所有成員都是值類型 如果引用類型比您擁有的所有引用類型多,則對基礎實例的更改將反映在查詢結果中。

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

是的,他們應該,而且 但是,您正在創建一個匿名類型為value字典 字典是可變的,但值(在這種情況下)不是可變的。

這是一個粗略的示例,顯示了一旦您填充匿名類型,就無法隱式更改其數據:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM