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

C#は確かに匿名型をサポートしていますが、本当の答えは次のとおりです。

いいえ、C#ではそれを行うことはできません。メソッドのすぐ上でプライベートとして宣言し、structそれを忘れてください。

于 2012-09-19T11:09:58.223 に答える
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 };


私はこのアプローチを採用しないと記録に残しています。個人的には、匿名型、、、Tuple<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();
    }

これにより、プロパティをその場で宣言することにより、必要に応じてプロパティを動的に追加できます。ExpandoObjectDLRが名前でメンバーを要求したときに、DLRに配管を提供するため、後でこれらを使用できます。

于 2012-09-19T11:11:40.283 に答える