Как уменьшить количество объявлений типов при использовании лямбда-параметров?

StackOverflow https://stackoverflow.com/questions/944650

Вопрос

Ниже приведена сильно урезанная версия некоторого кода, который у меня есть

public class DataInfo<T>
{
    public DataInfo(string description, Func<T, object> funcToGetValue)
    {
        this.description = description;
        this.funcToGetValue= funcToGetValue;
    }

    public readonly string description;
    public readonly Func<T, object> funcToGetValue;
}

public class DataType1
{
    public int fieldA { get; set; }
    public string fieldB { get; set; }
}

public class CurrentUse
{
    static List<DataInfo<DataType1>> data1 = new List<DataInfo<DataType1>>()
    {
        new DataInfo<DataType1>("someStuff", data => data.fieldA),
        new DataInfo<DataType1>("someOtherStuff", data => data.fieldB)
    };
}

(Существует много типов, и не волнуйтесь, на самом деле не все являются общедоступными!)

Это работает, и все в порядке, насколько это возможно, но тот факт, что я должен продолжать повторять new DataInfo<DataType1> меня это немного беспокоит.

Я попытался создать не общую вспомогательную версию DataInfo для создания объектов для меня следующим образом

public class DataInfo
{
    public static DataInfo<T> Create<T>(string description, Func<T, object> func)
    {
        return new DataInfo<T>(description, func);
    }
}
public class DesiredUse
{
    static List<DataInfo<DataType1>> data1 = new List<DataInfo<DataType1>>()
    {
        DataInfo.Create("someStuff", data => data.fieldA),
        DataInfo.Create("someOtherStuff", data => data.fieldB)
    };
}

Но это не работает, поскольку компилятор не может разрешить FieldA & FieldB, поскольку он не может определить тип данных.

Есть какие-нибудь идеи, как я могу избавиться от дублированной информации о типе?Я не возражаю вносить изменения, при условии, что в итоге у меня будет список источников данных

Это было полезно?

Решение

Я бы создал класс builder:

public sealed class DataInfoListBuilder<T> : IEnumerable
{
    private readonly List<DataInfo<T>> list = new List<DataInfo<T>>();

    public void Add(string description, Func<T, object> function)
    {
         list.Add(DataInfo.Create<T>(description, function));
    }

    public List<DataInfo<T>> Build()
    {
        return list;
    }

    public IEnumerator GetEnumerator()
    {
        throw new InvalidOperationException
            ("IEnumerator only implemented for the benefit of the C# compiler");
    }
}

Затем используйте его как:

static List<DataInfo<DataType1>> data1 = new DataInfoListBuilder<DataType1>
{
    { "someStuff", data => data.fieldA },
    { "someOtherStuff", data => data.fieldB }
}.Build();

Я не тестировал это, но я думаю, что это должно сработать.Вы могли бы сделать его универсальным типом в DataInfo, и в этом случае вы бы использовали:

static List<DataInfo<DataType1>> data1 = new DataInfo<DataType1>.Builder
{ ... }.Build();

Другие советы

Возможно, вы можете наследовать от List> и предоставить специализированный метод добавления:

public class SpecialList<T> : List<DataInfo<T>>
{
    public void Add(string description, Func<T, object> func)
    {
        base.Add(new DataInfo<T>(description, func));
    }
}

Затем вы можете использовать его следующим образом:

public class CurrentUse
{
    public static SpecialList<DataType1> Data1
    {
        get
        {
            SpecialList<DataType1> list = new SpecialList<DataType1>();
            list.Add("someStuff", data => data.fieldA);
            list.Add("someOtherStuff", data => data.fieldB);

            return list;
        }
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top