【问题标题】:Convert List<oneType> to IEnumerable<anotherType>将 List<oneType> 转换为 IEnumerable<anotherType>
【发布时间】:2014-11-03 20:56:30
【问题描述】:

我有一个listAdoParams,它是一个List&lt;AdoNetAppenderParameter&gt;

AdoNetAppenderParameterlog4net 库中的一个类型。

namespace log4net.Appender
{
  public class AdoNetAppenderParameter
    {
    public AdoNetAppenderParameter();
    public DbType DbType { get; set; }
    public IRawLayout Layout { get; set; }
    public string ParameterName { get; set; }
    public byte Precision { get; set; }
    public byte Scale { get; set; }
    public int Size { get; set; }

    public virtual void FormatValue(IDbCommand command, LoggingEvent loggingEvent);
    public virtual void Prepare(IDbCommand command);

    }
}

我想将此listAdoParams 转换为IEnumerable&lt;IDataParameter&gt;

namespace System.Data
{
  public interface IDataParameter
    {
    DbType DbType { get; set; }
    ParameterDirection Direction { get; set; }
    bool IsNullable { get; }
    string ParameterName { get; set; }
    string SourceColumn { get; set; }
    DataRowVersion SourceVersion { get; set; }
    object Value { get; set; }
     }
}

我应该如何进行这种转换?

【问题讨论】:

  • “应用程序不直接创建 IDataParameter 接口的实例,而是创建继承 IDataParameter 的类的实例。” ... 你需要一个继承自 IDataParameter 的类来转换 log4net 类型。

标签: c# linq c#-4.0 type-conversion ienumerable


【解决方案1】:

产生一种类型到另一种类型的一对一投影的常用方法是执行Select。如果新类型是接口,则必须先实现该接口:

class MyDataParameter : IDataParameter {
    DbType DbType { get; set; }
    ParameterDirection Direction { get; set; }
    bool IsNullable { get; }
    string ParameterName { get; set; }
    string SourceColumn { get; set; }
    DataRowVersion SourceVersion { get; set; }
    object Value { get; set; }
}

var res = initial.Select(
    p => new MyDataParameter {
        DbType = p.DbType
    ,   ParameterName = p.ParameterName
    ,   ... // and so on
    }
).Cast<IDataParameter>();

另一种方法是将AdoNetAppenderParameter 包装在MyDataParameter 的实例中:

class MyDataParameter : IDataParameter {
    private readonly AdoNetAppenderParameter wrapped;
    public MyDataParameter (AdoNetAppenderParameter w) {
        wrapped = w;
    }
    DbType DbType {
        get { return wrapped.DbType; }
        set { wrapped.DbType = value; }
    }
    ... // And so on
}

现在投影看起来会更简单:

var res = initial.Select(p => new MyDataParameter(p)).Cast<IDataParameter>();

【讨论】:

  • [MyDataParameter] 类是否可以包含 [Precision]、[Scale] 等额外字段,以便它们也是目标映射的一部分?
  • @GilliVilla MyDataParameter 类被隐藏。这个想法是仅通过IDataParameter 接口访问它。允许向其添加属性或方法,在这种情况下它是无用的:没有人只能看到 IDataParameter 将能够访问 PrecisionScale 等的附加属性。
猜你喜欢
  • 2012-02-24
  • 2018-08-04
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-29
相关资源
最近更新 更多