0

在 C# 中是否有一个很好的现有或即将推出的替代方法来声明方法中的数据结构?可以使用匿名类型,但声明它们有困难。假设我有一个假设的课程:

class ThingsManager
{
    private void DoThings(IEnumerable<Thing> things)
    {
        var thingLocations = new Dictionary<string, string>();

        foreach(var thing in things)
        {
            // some complicated logic and checks for current thing;
            // if current thing satisfies all conditions:

            var thingName = thing.Name;
            var thingLocation = location; // taken somewhere from upper lines
            thingLocations.Add(thingName, thingLocation);
        }

        // ... later

        foreach(var thingLocation in thingLocations)
        {
            // here I don't know what is the key and what does the value mean.
            // I could use Linq and anonymous types, but sometimes it is clearer 
            // to use foreach if the logic is complicated
        }
    }
}

现在,我想看到什么:

class ThingsManager
{
    private void DoThings(IEnumerable<Thing> things)
    {
        struct ThingLocations
        {
            string ThingName {get;set;}
            string Location {get;set;}
        }

        var thingLocations = new List<ThingLocations>();

        foreach(var thing in things)
        {
            // some complicated logic and checks for current thing;
            // if current thing satisfies all conditions:

            var thingName = thing.Name;
            var thingLocation = location; // taken somewhere from upper lines
            thingLocations.Add(new ThingLocation(thingName, thingLocation));
        }

        // ... later

        foreach(var thingLocation in thingLocations)
        {
            // now here I can use thingLocation.ThingName  
            // or thingLocation.Location
        }
    }
}

我也可以在类中声明结构,但在我的函数之外的任何地方使用它都没有意义。如果我的函数是唯一可以使用此数据结构的地方会更好。我正在寻找一种更好的方法来处理这种情况,或者至少能够声明匿名类型。

4

2 回答 2

0

匿名类型将有助于命名方面,但您必须将输入转换为您的匿名类型,并且该类型将保留在方法范围的内部。

// Assumes thingLocation comes from somewhere...
var thingLocations = things
    .Select(t => new { ThingName = t.Name, Location = new ThingLocation(t.Name, thingLocation) } );

它是使用Select扩展方法完成的,以便投影到匿名类型。

您可以在没有 linq 的情况下声明匿名类型,但您会发现尝试将它们添加到列表/字典中很烦人:

var me = new { Name = "Adam", Age = 27 };


我要郑重声明我不会采用这种方法,我个人会使用匿名类型、aTuple<string, string>或自定义类型。

如果所有这些都失败了,如果你不介意启动 DLR,你可以使用ExpandoObject

    class Thing
    {
        public string Name;
    }

    static void Main(string[] args)
    {
        var things = new List<Thing>() { new Thing { Name = "Adam" } };
        var thingLocations = new List<dynamic>();

        foreach (var thing in things)
        {
            dynamic location = new ExpandoObject();
            location.Name = thing.Name;
            location.Location = "here";

            thingLocations.Add(location);
        }

        // ... later

        foreach(var thingLocation in thingLocations)
        {
            Console.WriteLine(thingLocation.Name);
            Console.WriteLine(thingLocation.Location);
        }

        Console.ReadLine();
    }

这允许您通过在现场声明它们来根据需要动态添加属性。然后您可以稍后使用这些,因为ExpandoObject当 DLR 按名称要求成员时,它会为 DLR 提供管道。

于 2012-09-19T11:11:40.283 回答
0

C# does indeed support Anonymous Types, but the real answer is:

No, you can't do that in C#. Just declare the struct as private right above your method and forget about it.

于 2012-09-19T11:09:58.223 回答