【问题标题】:Inheriting from an interface with properties of the same name从具有相同名称的属性的接口继承
【发布时间】:2015-04-29 11:56:05
【问题描述】:

我有一个接口 IProduct 和两个部分类 SearchedProductInternal 和 SearchedProductExternal。 这两个类是来自 3rd 方 Web 服务搜索的扩展类,但它们返回的结果类型略有不同。 我想对两者都使用接口,所以它们返回的类型是相同的。我知道如何继承,但我该怎么做才能返回“名称”,因为接口和 SearchedProductInternal 具有相同的对象名称?

我的界面类似如下:

   public interface IProduct
        {  
            string Name { get; }
            string ID { get; }
            string DescriptionShort { get; }
            string DescriptionLong { get; }
         } 

我的对象 SearchedProductInternal 具有以下属性:

     string Name; 
     int ObjectIdField;
     string DescriptionShortField;
     string DescriptionLongField;

所以这是我继承的地方

  public partial class SearchedProductInternal : IProduct
        {

            public string ID
            {
                get { return ObjectIdField.ToString(); }
            }
            public string Name
            {
                //What do I do here?
            }
            public string DescriptionShort{get { return shortDescriptionField; }
            }

            public string DescriptionLong {get { return longDescriptionField; }
            }
}

我想返回在 SearchedProductInternal 类中分配的原创名称,但我不知道该怎么做,因为如果我只是放

return Name

我收到一个 stackoverflow 错误,因为它似乎一直在调用它自己?

【问题讨论】:

  • 重命名 SearchedProductInternal 类的变量
  • 你想叫什么名字?在另一个 Partial 类中是否有 Name 的显式实现?
  • @jehof 我无法重命名搜索到的产品内部类中的任何内容,因为这是我从第 3 方网络服务获得的东西,我只是针对它创建了一个部分类,因此我可以从我的界面继承。
  • @MichalCiechan 我想从 OriginalSearchedProductInternal 中调用这个名称。我通过使其成为部分来扩展它。想我会更新我的问题以使其更清楚
  • 通过局部化来扩展?除非您从 3rd 方供应商处获取 SearchedProductInternal 作为 .cs 文件并对其进行编译,否则这将不起作用,使部分内容仅告诉编译器在不同的 .cs 文件中期望更多的类,它不会扩展运行时类型。

标签: c# inheritance


【解决方案1】:

我认为你应该在这里做的是显式实现接口,这样你就可以同时拥有类中定义的 Name 属性和接口中的 IProduct.Name 属性。

【讨论】:

  • 你能举个例子吗。我不明白你的意思?
  • 你可以有类似的东西: public partial class SearchedProductInternal : IProduct { public string Name { } string IProduct.Name { } }
【解决方案2】:

你可以explicitly implement这个界面,像这样:

public partial class SearchedProductInternal : IProduct
{
    string IProduct.ID
    {
        get { return ObjectIdField.ToString(); }
    }

    string IProduct.Name
    {
        get { return "Interface name"; }
    }

    string IProduct.DescriptionShort
    {
        get { return shortDescriptionField; }
    }

    string IProduct.DescriptionLong 
    {
        get { return longDescriptionField; }
    }

    // Name property for the class, not the interface
    public string Name
    {
        get { return "Class name";  }
    }
}

通过这种方式,您可以区分对接口属性的调用和类中具有相同名称的属性的调用。

当访问这两个属性时,您还可以通过以下方式决定您想要哪个:

    var test = new SearchedProductInternal();       
    Console.WriteLine(test.Name); // returns "Class name"
    Console.WriteLine((test as IProduct).Name); // returns "Interface name"

【讨论】:

  • 显式实现接口时需要省略访问修饰符。
【解决方案3】:

如果您的 SearchedProductInternal 已经定义了属性 Name 并且您尝试返回相同的 Name 属性的值,则您无需执行任何操作。

不要再创建一个名为 Name 的属性。只需摆脱您添加的 Name 属性。一切都应该正常工作,因为该类已经实现了接口 IProduct 定义的协定。

如果你想从IProduct.Name属性返回不同的值,你可以使用explicit interface implementation

【讨论】:

    【解决方案4】:

    在这种情况下,您必须更改变量的名称 Name。

    如果这是一个模棱两可的句子,请记住它对于 PC 也是一样的。名字不能是两个东西。但 Name 和 _Name 可以。

    public class SearchedProductInternal : IProduct
    {
        string _name = "test";
        public string Name
        {
            get
            {
                return _name;
            }
        }
    }
    public interface IProduct
    {
        string Name { get; }
    }
    

    【讨论】:

      【解决方案5】:

      我同意上面的回答。但是这里有个小问题,我们不能将接口成员公开,因为它会导致编译错误。

      我们可以同时拥有类级别和接口级别的成员。接口成员不能通过类实例访问,只能通过接口实例访问。

      public interface IProduct
      {
          string Name { get; }
          string ID { get; }
          string DescriptionShort { get; }
          string DescriptionLong { get; }
      }
      
      public partial class SearchedProductInternal : IProduct
      {
          private string _clsName;
      
          private string _interfaceName;
          private string _objectID;
          private string _shortDesc;
          private string _longDesc;
      
          public SearchedProductInternal(string _cName, string _iName)
          {
              _clsName = _cName;
              _interfaceName = _iName;
          }
      
          public string Name
          {
              get { return _clsName; }
          }
      
          string IProduct.Name
          {
              get { return _interfaceName; }
          }
      
          string IProduct.ID
          {
              get { return _objectID; }
          }
      
          string IProduct.DescriptionShort
          {
              get { return _shortDesc; }
          }
      
          string IProduct.DescriptionLong
          {
              get { return _longDesc; }
          }
      }
      
      class Program
      {
          static void Main(string[] args)
          {
              SearchedProductInternal clsSearchProduct = new SearchedProductInternal("clsName", "interfaceName");
              Console.WriteLine(clsSearchProduct.Name);
      
              IProduct interfaceProduct = (IProduct)clsSearchProduct;
              Console.WriteLine(interfaceProduct.Name);
      
              Console.ReadLine();
          }
      }
      

      【讨论】:

        【解决方案6】:

        我不确定我是否只是以一种不被理解的方式解释了这一点,但我让它工作的方式是使用 {get;set;}

        public partial class SearchedProductInternal : IProduct
            {
        
                public string ID
                {
                    get { return ObjectIdField.ToString(); }
                }
                public string Name  {get;set;}
        
                public string DescriptionShort{get { return shortDescriptionField; }
                }
        
                public string DescriptionLong {get { return longDescriptionField; }
                }
        

        }

        【讨论】:

          猜你喜欢
          • 2011-01-23
          • 2016-08-06
          • 2013-08-01
          • 1970-01-01
          • 2011-02-19
          • 1970-01-01
          • 2020-10-18
          • 2011-07-29
          相关资源
          最近更新 更多