繁体   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