2

私は、データ構造をループして辞書を構築する以下のコードを持っています。

このコードを複数回複製しましたが、唯一の違いは辞書へのキーです

したがって、以下のコードではたまたま次のようになります。

  task.Project + task.Name

それが辞書のキーですが、それ以外の場合は次のとおりです。

 task.Project

あるいは単に

 task.Name

これは、ハードコードされた「バケット」メソッドの 1 つの例です。

私の目標は、キーを計算するための関数にコールバックまたは何らかの方法で渡すことができる汎用の「バケット」メソッドを持つことです。

これを行う最良の方法は何ですか??

private Dictionary<string, TeamHours> BucketByProjectTask(Dictionary<string, TimeBooking> timebookings)
{
    Dictionary<string, TeamHours> dict = new Dictionary<string, TeamHours>();

    foreach (var name in timebookings.Keys)
    {
        TimeBooking tb = timebookings[name];
        Person p = tb.Person;

        foreach (var booking in tb.WeeklyTimeBookings.Keys)
        {
            var item = tb.WeeklyTimeBookings[booking];
            foreach (var task in item.TaskSlices)
            {
                if (dict.ContainsKey(task.Project + task.Name))
                {
                    TeamHours th = dict[task.Project + task.Name];
                    th.Hours = th.Hours + task.Hours;
                }
                else
                {
                    TeamHours th = new TeamHours();
                    th.Hours = task.Hours;
                    th.Project = task.Project;
                    th.Task = task.Name;
                    th.Workstream = tb.Person.OrganisationalUnitName;
                    dict[task.Project + task.Name] = th;
                }
            }

        }

    }
    return dict;
}
4

1 に答える 1

2

まあ、あなたはほとんど自分で質問に答えました。デリゲートをメソッドに渡すか、さまざまな実装を継承し、抽象メソッドを実装して特殊化します。もう 1 つのオプションは、鍵構築アルゴリズムをインターフェイスとして分離することです。これにより、懸念事項が最適に分離されますが、単純なシナリオではオーバーヘッドが大きすぎる可能性があります。

オプション 1 — デリゲート

private Dictionary<string, TeamHours> BucketByProjectTask(Dictionary<string, TimeBooking> timebookings, Func<string, Task> getTaskKey)
{
    …
    dict[getTaskKey(task)] = th;
    …
}

高度にローカライズされたシナリオ (つまり、単一のクラスにプライベートな実装と使用法) での使用に適しており、単純なキー構築式がいくつかあります。

オプション 2 — 抽象クラスとメソッド

class abstract BucketAlgorithm
{
    protected abstract string GetTaskKey(Task task);


    public  Dictionary<string, TeamHours> BucketByProjectTask(Dictionary<string, TimeBooking> timebookings)
    {
        …
        dict[GetTaskKey(task)] = th;
        …
    }
}

class SpecificBucketAlgorithm : BucketAlgorithm
{
    protected override string GetTaskKey(Task task) { … }
}

関心事 (実装からのインターフェイス) をより適切に分離する必要がない、またはいくつかの重要なキー構築アルゴリズムが必要な、1 つのアセンブリのような中程度の範囲内での使用に適しています。

オプション 3 — インターフェイスに分解

interface ITaskKeyGenerator
{
    string GetTaskKey(Task task);
}

class BucketAlgorithm
{
    public BucketAlgorithm(ITaskKeyGenerator taskKeyGenerator)
    {
        this.taskKeyGenerator = taskKeyGenerator;
    }

    private ITaskKeyGenerator taskKeyGenerator;

    public  Dictionary<string, TeamHours> BucketByProjectTask(Dictionary<string, TimeBooking> timebookings)
    {
        …
        dict[taskKeyGenerator.GetTaskKey(task)] = th;
        …
    }
}

懸念事項の完全な分離が必要なシナリオ、または複数の複雑なキー構築アルゴリズムが存在するシナリオ、または API のユーザーによって「外部」から提供されるシナリオに適しています。

于 2010-12-31T18:10:30.383 に答える