基于泛型类型实现属性的正确方式

本文关键字:方式 属性 泛型类型 实现 | 更新日期: 2023-09-27 18:27:24

我有以下接口

public interface IRepository<T> where T : IEntity, new()
{
    List<T> GetAll();
}

我在这里实现了

public abstract partial class WhsePricingRatesAddOnProviderBase : WhsePricingRatesAddOnProviderBaseCore, IRepository<WhsePricingRatesAddOn>
{
    /// <summary>
    /// Gets all rows from the DataSource.
    /// </summary>
    /// <returns>Returns a TList of Entity objects.</returns>
    public override List<WhsePricingRatesAddOn> GetAll()
    {
        return base.GetAll();
    }
}

还有这里的

我在这里实现了

public abstract partial class WhsePricingRatesAddOn2ProviderBase : WhsePricingRatesAddOn2ProviderBaseCore, IRepository<WhsePricingRatesAddOn2>
{
    /// <summary>
    /// Gets all rows from the DataSource.
    /// </summary>
    /// <returns>Returns a TList of Entity objects.</returns>
    public override List<WhsePricingRatesAddOn2> GetAll()
    {
        return base.GetAll();
    }
}

当我尝试在类中使用它时

 public class TypeRate
    {
        public IRepository Repository { get; set; }
        public TypeRate(int i)
        {
    if (i == 1)
            {
                Repository = (IRepository<WhsePricingRatesAddOn>)SCMSDevMaster.Data.DataRepository.WhsePricingRatesAddOnProvider;}
    else
            {
                Repository = (IRepository<WhsePricingRatesAddOn2>)SCMSDevMaster.Data.DataRepository.WhsePricingRatesAddOn2Provider;}
            }
        }
    }

如果我不把<T> 在IRepository声明之后

使用泛型类型"IRepository<T> "需要一个参数。

或者如果我把它放进去,我就会得到

找不到命名空间名称"T"的类型错误

我希望我的TypeRate类在运行时创建之前不知道T,此时我将用代码为存储库设置正确的T。

我是不是看错了?

我应该指出SCMSDevMaster.Data.DataRepository.WhesePricingRatesAddOnProvider是静态的;

基于泛型类型实现属性的正确方式

问题是您的Repository属性声明-您只需要指定类型参数,如果您只有一种类型可以工作,则可以直接指定类型参数:

public IRepository<WhsePricingRatesAddOn> Repository { get; set; } 

我不明白你为什么说你希望TypeRate不知道T的类型,因为它在构造函数中已经明确设置了。。。

也可以使TypeRate成为泛型(即使其成为TypeRate<T>并将属性声明为IRepository<T>),但构造函数主体不会编译,因为它显式转换为IRepository<WhsePricingRatesAddOn>

你可以引入一个非通用IRepository接口作为IRepository<T>的超级接口,但你已经有了IEntity,你所添加的只是依赖于TGetAll()方法。。。

从根本上说,我认为您确实需要决定哪些信息在编译时是已知的,哪些信息只在执行时才是已知的——因为听起来您目前的需求不一致。

此定义

public IRepository Repository { get; set; } 

不完整,因为没有名为IRepository的类(或接口)。有一个通用接口有一个名为IRepository的类型参数,但那是另一回事。

用具体指定的类型声明Repository,如下所示:

public IRepository<WhsePricingRatesAddOn> Repository { get; set; } 

另一方面,如果您需要不同类型的存储库,问题将是:

SCMSDevMaster.Data.DataRepository.WhsePricingRatesAddOnProvider

这是尽可能具体的。我看不出你如何在不进行重大重新设计的情况下使该部分充满活力,我也没有足够的信息来提供进一步的建议。

您可以尝试使用泛型方法,而不是泛型接口。然后,您不必使用特定类型来声明您的IRepository接口。

public interface IRepository
{
    List<T> GetAll<T>() where T : IEntity;
}
public class TypeRate
{
    public IRepository Repository { get; private set; } 
    public TypeRate(IRepository repository)
    {
         Repository = repository;
    }
    public List<YourType> Get()
    {
        return this.Repository.GetAll<YourType>();
    }
}