如何将类的实例传递给c#中的另一个类?

时间:2016-07-06 20:48:24

标签: c#

我有一个看起来像这样的课程

public class TableMapper<TSource>
{
    ....
    ....
    public TableMapper(IQueryExtractor queryExtractor, string tableAliasPrefix = null)
    {
        QueryExtractor = queryExtractor;

        TableAliasPrefix = tableAliasPrefix;
    }

    ....
    ....
}

我从另一个类中创建了这个类的实例,如此

public class CustomerMapper : ReportTemplate
{
    private readonly IQueryExtractor QueryExtractor;

    private readonly TableMapper<Customer> customerMapper;

    private readonly TableMapper<Client> clientMapper;

    public CustomerMapper(DbContext context)
        : base(new QueryBuilder(), new QueryExecutor(context.Database.Connection.ConnectionString))
    {
        QueryExtractor = new QueryExtractor(context);

        customerMapper = new TableMapper<Customer>(QueryExtractor, "Customer");

        clientMapper = new TableMapper<Client>(QueryExtractor);
    }

    public List<IReportRelation> ReportRelations
    {

        return new List<IReportRelation>
            { 
                new ReportRelation
                {
                    ForeignColumn = customerMapper.GetReportColumn(x => x.ClientId),
                    LocalColumn = clientMapper.GetReportColumn(x => x.Id),
                },
            };
    }

}

正如您在ReportRelations方法中看到的,我返回ReportRelation实现列表。我需要做的是在我的IReportRelation界面和ReportRelation实现中再添加2个公共属性来保存我TableMapper<TSource>类的实例

如何在IReportRelation接口中定义一个具有customerMapper属性的副本/实例的公共变量?

以下是我的IReportRelation定义

的方式
public interface IReportRelation
{
    //Here I need to add an instance that hold the localTable
    //something like this TableMapper<TSource> LocalMapper
    //something like this TableMapper<TSource> ForeignMapper

    IReportColumn ForeignColumn { get; set; }

    IReportColumn LocalColumn { get; set; }
}

已更新

在Tim的建议下面我将我的代码更改为以下

public interface IReportRelation<TLocal, TForeign>
{
    TableMapper<TLocal> LocalMapper { get; set;}

    TableMapper<TForeign> ForeignMapper { get; set; }

    IReportColumn ForeignColumn { get; set; }

    IReportColumn LocalColumn { get; set; }
}

然后在我的CustomerMapper课程中,我的功能将如下所示

public List<IReportRelation<Customer,Client> ReportRelations
    {

        return new List<IReportRelation<Customer,Client>>
            { 
                new ReportRelation<Customer,Client>
                {
                                    LocalMapper = this.customerMapper,
                    ForeignMapper = this.clientMapper,
                    ForeignColumn = customerMapper.GetReportColumn(x => x.ClientId),
                    LocalColumn = clientMapper.GetReportColumn(x => x.Id),

                },
            };
    }

但问题是ReportRelations将始终返回IReportRelation<Customer,Client>列表。如果我想返回类似这样的混合列表,例如

,该怎么办?
    public List<IReportRelation<Customer,Client> ReportRelations
    {

        return new List<IReportRelation<Customer,Client>>
            { 
                new ReportRelation<Customer,Client>
                {
                                    LocalMapper = this.customerMapper,
                    ForeignMapper = this.clientMapper,
                    ForeignColumn = customerMapper.GetReportColumn(x => x.ClientId),
                    LocalColumn = clientMapper.GetReportColumn(x => x.Id),

                },

                new ReportRelation<Customer,Team>
                {
                    LocalMapper = this.customerMapper,
                    ForeignMapper = this.teamMapper,
                    ForeignColumn = customerMapper.GetReportColumn(x => x.TeamId),
                    LocalColumn = clientMapper.GetReportColumn(x => x.Id),
                },
            };
    }

2 个答案:

答案 0 :(得分:2)

您不能在列表中混合使用不同的泛型类型参数。这个问题的一个常见解决方案是拥有一个非通用的基本接口,并从中派生出通用接口。

public interface ITableMapper
{
    // Use Sytem.Type arguments where appropriate and
    // the object type instead of generic types
    ...
}

public class TableMapper<TSource> : ITableMapper
{
    ...
}
public interface IReportRelation
{
    ITableMapper LocalMapper { get; }
    ITableMapper ForeignMapper { get; }

    IReportColumn ForeignColumn { get; set; }
    IReportColumn LocalColumn { get; set; }
}

public interface IReportRelation<TLocal, TForeign> : IReportRelation
{
    new TableMapper<TLocal> LocalMapper { get; set; }
    new TableMapper<TForeign> ForeignMapper { get; set; }
}
public class ReportRelation<TLocal, TForeign> : IReportRelation<TLocal, TForeign>
{
    ITableMapper IReportRelation.LocalMapper { get { return LocalMapper; } }
    ITableMapper IReportRelation.ForeignMapper { get { return ForeignMapper; } }

    public TableMapper<TLocal> LocalMapper { get; set; }
    public TableMapper<TForeign> ForeignMapper { get; set; }

    public IReportColumn ForeignColumn { get; set; }
    public IReportColumn LocalColumn { get; set; }
}

确保明确实现非通用接口。当直接与班级合作时,这会隐藏它。

现在您可以拥有List<IReportRelation>并填写具有不同泛型类型参数的ReportRelation<TLocal, TForeign>个对象。

您可以在.NET Framework Libary中找到此模式。请参阅IList<T> : IListIEnumerable<T> : IEnumerable,依此类推......

答案 1 :(得分:0)

我认为ClientCustomer可能会发生变化。在这里你可以做什么:

public interface IReportRelation<TLocal, TForeign>
{
    TableMapper<TLocal> LocalMapper { get; set; }
    TableMapper<TForeign> ForeignMapper { get; set; }

    IReportColumn ForeignColumn { get; set; }
    IReportColumn LocalColumn { get; set; }
}

public class ReportRelation<TLocal, TForeign> : IReportRelation<TLocal, TForeign>
{
    public TableMapper<TLocal> LocalMapper { get; set; }
    public TableMapper<TForeign> ForeignMapper { get; set; }

    public IReportColumn ForeignColumn { get; set; }
    public IReportColumn LocalColumn { get; set; }
}

适用于您的CustomMapper班级

public class CustomerMapper : ReportTemplate
{
    ...

    public List<IReportRelation<Customer, Client>> ReportRelations
    {
        return new List<IReportRelation<Customer, Client>>
        { 
            new ReportRelation<Customer, Client>
            {
                LocalMapper = this.customerMapper,
                ForeignMapper = this.clientMapper,
                ForeignColumn = customerMapper.GetReportColumn(x => x.ClientId),
                LocalColumn = clientMapper.GetReportColumn(x => x.Id)
            }
        };
    }
}