C# 为什么派生类接口的引用显示基类的字段?

C# 为什么派生类接口的引用显示基类的字段?,c#,class,inheritance,interface,C#,Class,Inheritance,Interface,我正在创建一个具有属性的抽象基类,并在派生类中继承该基类。派生类继承基类和接口。当我尝试使用接口引用派生类的对象时,我也看到了基类的属性,这些属性没有在派生类接口中声明。最初的代码有点大,但下面的方法和我遵循的方法相同 基类: public class PromotionBase : IPromotionBase { private string CurrentPromotion = string.Empty; public PromotionBase(string promot

我正在创建一个具有属性的抽象基类,并在派生类中继承该基类。派生类继承基类和接口。当我尝试使用接口引用派生类的对象时,我也看到了基类的属性,这些属性没有在派生类接口中声明。最初的代码有点大,但下面的方法和我遵循的方法相同

基类:

public class PromotionBase : IPromotionBase
{
    private string CurrentPromotion = string.Empty;
    public PromotionBase(string promotionName)
    {
        CurrentPromotion = promotionName;
    }
    public DateTime? StartDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.StartDate));
    public DateTime? EndDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.EndDate));
    public string PromoCode => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.PromoCode));
    public DateTime? OrderQualificationStartDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.OrderQualificationStartDate));
    public DateTime? OrderQualificationEndDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.OrderQualificationEndDate));
    public int DiscountPercentage => SettingsManager.GetSettingInt(CurrentPromotion, nameof(this.DiscountPercentage));
    public int UsageLimit => SettingsManager.GetSettingInt(CurrentPromotion, nameof(this.UsageLimit));
    public string ActivePromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.ActivePromoTile));
    public string EligiblePromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.EligiblePromoTile));
    public string AddedPromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.AddedPromoTile));
    public string VerifiedPromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.VerifiedPromoTile));
}
public class FreeGiftAndShippingPromotionManager : PromotionBase,IFreeGiftAndShippingPromo
{
    public FreeGiftAndShippingPromotionManager() : base(PromotionHelper.PromoName.FreeGiftAndShipping)
    {
    }
    private static Dictionary<int, ProductItemInfo> productItemInfos = null;
    private static DateTime LastProductInfoRefresh = DateTime.MinValue;
    private const int InfoRefreshInterval = 30;
    private const int LowStockLevel = 10;
    public override int GiftProductItemId
    {
        get
        {
            string defaultProductId = "0";
            if(string.IsNullOrEmpty(GiftProductItemIds).Not())
            {
                defaultProductId = "0" + GiftProductItemIds.Split(',').FirstOrDefault();
            }
            return Convert.ToInt32(defaultProductId);
        }
    }
            public ProductItemInfo GetProductInfo(int productItemId)
    {
        GetFreshProductInfos();
        return productItemInfos[productItemId];
    }
}
public interface IFreeGiftAndShippingPromo
{
    DateTime? StartDate { get; }
    DateTime? EndDate { get; }
    string PromoCode { get; }
    DateTime? OrderQualificationStartDate { get; }
    DateTime? OrderQualificationEndDate { get; }
    int PurchaseThreshold { get; }
    int DisplayPriority { get; }
    bool IsActive { get; }
    string PromoTitle { get; }
    string PromoIntro { get; }
    int GiftProductItemId { get; }
    string GiftProductItemIds { get; }
    bool ShowPopup { get; }
    bool OrderMeetsPromoMinPurchase(Order order);
    string GetCartPromoTile(Order order);
    bool OrderEligibleForFreeGift(Order order);
    string EligiblePromoTile { get; }
    string AddedPromoTile { get; }
    string VerifiedPromoTile { get; }
    ProductItemInfo GetProductInfo(int productItemId);
    string GetCartProductGridDisplay();
}
派生类:

public class PromotionBase : IPromotionBase
{
    private string CurrentPromotion = string.Empty;
    public PromotionBase(string promotionName)
    {
        CurrentPromotion = promotionName;
    }
    public DateTime? StartDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.StartDate));
    public DateTime? EndDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.EndDate));
    public string PromoCode => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.PromoCode));
    public DateTime? OrderQualificationStartDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.OrderQualificationStartDate));
    public DateTime? OrderQualificationEndDate => SettingsManager.GetSettingDateTime(CurrentPromotion, nameof(this.OrderQualificationEndDate));
    public int DiscountPercentage => SettingsManager.GetSettingInt(CurrentPromotion, nameof(this.DiscountPercentage));
    public int UsageLimit => SettingsManager.GetSettingInt(CurrentPromotion, nameof(this.UsageLimit));
    public string ActivePromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.ActivePromoTile));
    public string EligiblePromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.EligiblePromoTile));
    public string AddedPromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.AddedPromoTile));
    public string VerifiedPromoTile => SettingsManager.GetSettingString(CurrentPromotion, nameof(this.VerifiedPromoTile));
}
public class FreeGiftAndShippingPromotionManager : PromotionBase,IFreeGiftAndShippingPromo
{
    public FreeGiftAndShippingPromotionManager() : base(PromotionHelper.PromoName.FreeGiftAndShipping)
    {
    }
    private static Dictionary<int, ProductItemInfo> productItemInfos = null;
    private static DateTime LastProductInfoRefresh = DateTime.MinValue;
    private const int InfoRefreshInterval = 30;
    private const int LowStockLevel = 10;
    public override int GiftProductItemId
    {
        get
        {
            string defaultProductId = "0";
            if(string.IsNullOrEmpty(GiftProductItemIds).Not())
            {
                defaultProductId = "0" + GiftProductItemIds.Split(',').FirstOrDefault();
            }
            return Convert.ToInt32(defaultProductId);
        }
    }
            public ProductItemInfo GetProductInfo(int productItemId)
    {
        GetFreshProductInfos();
        return productItemInfos[productItemId];
    }
}
public interface IFreeGiftAndShippingPromo
{
    DateTime? StartDate { get; }
    DateTime? EndDate { get; }
    string PromoCode { get; }
    DateTime? OrderQualificationStartDate { get; }
    DateTime? OrderQualificationEndDate { get; }
    int PurchaseThreshold { get; }
    int DisplayPriority { get; }
    bool IsActive { get; }
    string PromoTitle { get; }
    string PromoIntro { get; }
    int GiftProductItemId { get; }
    string GiftProductItemIds { get; }
    bool ShowPopup { get; }
    bool OrderMeetsPromoMinPurchase(Order order);
    string GetCartPromoTile(Order order);
    bool OrderEligibleForFreeGift(Order order);
    string EligiblePromoTile { get; }
    string AddedPromoTile { get; }
    string VerifiedPromoTile { get; }
    ProductItemInfo GetProductInfo(int productItemId);
    string GetCartProductGridDisplay();
}
我创建了这个结构,所以当我引用派生类的接口时,我只得到派生类接口中的属性

但是当我像这样引用派生类的接口时

private IFreeGiftAndShippingPromo Instance_FreeGiftAndShippingPromoManager = new FreeGiftAndShippingPromotionManager();
我还可以看到基类的activepromotive属性和所有其他基类属性。我可以知道为什么吗?有没有办法只获取在派生类接口中声明的成员


非常感谢。

调试器显示界面中保存的实际类型,即您在窗口中看到的类型。如果您试图在代码中实际使用
activepromotive
,代码将不会编译。

调试器显示界面中保存的实际类型,即您在窗口中看到的类型。如果您试图在代码中实际使用
ActivePromotive
,代码将无法编译。

您能否提供一行代码来澄清“我可以看到ActivePromotive属性”的含义?(很明显,您可以在调试器中看到源代码和属性,但我怀疑这是您要问的问题)。@AlexeiLevenkov我添加了调试器的屏幕截图。希望这有助于理解。如果你还需要什么,请告诉我。我很乐意提供更多细节。你能提供一行代码来澄清“我能看到ActivePromotive属性”的含义吗?(很明显,您可以在调试器中看到源代码和属性,但我怀疑这是您要问的问题)。@AlexeiLevenkov我添加了调试器的屏幕截图。希望这有助于理解。如果你还需要什么,请告诉我。我很乐意提供更多细节。谢谢@Scott。当我尝试使用它时,它确实没有在智能意义上显示出来。糟糕的是,我太专注于显示属性的调试器了,这是我忘记尝试使用该实例并进行检查的原因。谢谢@Scott。当我尝试使用它时,它确实没有在智能意义上显示出来。糟糕的是,我太专注于显示属性的调试器了,而我忘记了尝试使用该实例并检查它。