适当的方式基于泛型类型的实现属性

时间:2013-08-12 13:30:56

标签: c# generics interface

我有以下界面

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

如果我不放&lt; T&gt;我会得到此错误在IRepository声明之后

  

使用泛型类型'IRepository&lt; T&gt;'需要一个论点。

或者如果我把它,那么我得到

  

无法找到命名空间名称“T”的类型错误

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

我是以错误的方式看待这个吗?

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

3 个答案:

答案 0 :(得分:3)

问题是你的Repository属性声明 - 你只需要指定一个类型参数,你可以直接这样做,因为你只有一种类型可以工作,它的外观:

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

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

也可以使TypeRate通用(即使它成为TypeRate<T>并将你的属性声明为IRepository<T>),但是构造函数体不会编译,因为它明确地转换为IRepository<WhsePricingRatesAddOn>

您可以将非通用 IRepository接口作为IRepository<T>的超级接口引入 - 但您已经拥有IEntity,您要添加的是GetAll()方法,它依赖于T ...

从根本上说,我认为你真的需要决定在编译时知道哪些信息,以及在执行时只知道哪些信息 - 因为听起来你现在的要求不一致。

答案 1 :(得分:3)

这个定义

public IRepository Repository { get; set; } 

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

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

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

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

SCMSDevMaster.Data.DataRepository.WhsePricingRatesAddOnProvider

尽可能具体。我没有看到你如何在没有重大设计的情况下使这部分成为动态,而且我没有足够的关于你的设计的信息来提供进一步的建议。

答案 2 :(得分:0)

您可以尝试使用通用方法而不是通用接口。然后,您不必使用特定类型声明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>();
    }
}