【问题标题】:How to reduce type declarations when using lambda parameters?使用 lambda 参数时如何减少类型声明?
【发布时间】:2009-06-03 13:10:00
【问题描述】:

以下是我拥有的一些代码的大幅缩减版本

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&lt;DataType1&gt;这一事实让我有点困扰。

我尝试创建一个非通用的 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,因为它无法推断数据的类型。

有什么办法可以去掉重复的类型信息吗?我不介意进行更改,只要我最终得到一个 DataInfos 列表

【问题讨论】:

    标签: c# generics lambda type-inference


    【解决方案1】:

    我会创建一个构建器类:

    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();
    

    【讨论】:

      【解决方案2】:

      您可以从 List> 继承并提供专门的 add 方法:

      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;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2018-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多