【问题标题】:C# Properties in interfaces & abstract classes接口和抽象类中的 C# 属性
【发布时间】:2013-12-31 00:47:54
【问题描述】:

我只是在编写一个简单的 C# 接口,并在其中放置了一个属性,并没有考虑太多。例如:

public interface IMyInterface
{
    string Name { get; set; }
    object[][] Data { get; set; 
}

我意识到当应用于接口和抽象基类时,我对属性有点困惑。在普通类中,这种语法会为它在后台生成的隐藏字符串成员生成访问器和修改器。

接口不应该有数据成员。那么,在这种情况下,这种语法有什么不同吗?

抽象类呢?如果我将相同的语法放在抽象基类和派生类中,两者都会以隐藏成员结束吗?

【问题讨论】:

    标签: c# .net-4.0


    【解决方案1】:

    接口不应该有数据成员。

    那些是属性,那些areallowed

    接口仅包含方法、属性、事件或索引器的签名。

    另见c# properties on Interface。 至于你的第二个问题:

    如果我将相同的语法放在抽象基类和派生类中,是否都会以隐藏成员结束?

    是的。您可以通过在基类上标记属性virtual 和在派生类上标记override 来防止这种情况发生。

    【讨论】:

    • 明确一点,当你说“那些是属性,那些是允许的”时,你的意思是声明是允许的,对吧?因此,相同的语法将在接口中声明属性,但不提供支持数据项。实现接口的类实现属性并提供支持数据项。如果我仍然错了,请纠正我:)谢谢!
    【解决方案2】:

    接口不应该有数据成员。那么,这种语法在这种情况下会有所不同吗?

    技术上它不是一个数据成员——它是一个拥有基础数据成员的get/set方法对。没有实现。

    抽象类呢?如果我将相同的语法放在抽象基类和派生类中,两者都会以隐藏成员结束吗?

    如果 class 是抽象的并且属性是 virtual,那么是的,您将用另一个自动实现的属性覆盖一个自动实现的属性(这是没有意义的)。

    如果类是抽象类并且属性不是virtual,那么您仍然有两个实现,但基类隐藏父实现而不是覆盖它(如果它们都是自动实现的,这仍然毫无意义)。

    如果属性是抽象的,那么抽象类将没有实现。您将必须在您的具体类中实现 get/set(可以自动实现 bot 而不是必须) .

    【讨论】:

      【解决方案3】:

      接口中的属性声明与实现完全分开。因此,您可以使用自动属性来实现它

          private class MyImpl : IMyInterface
          {
              public string Name { get; set; }
              public object[][] Data { get; set; }
          }
      

      或声明您自己的支持字段

          private class MyImplBacked : IMyInterface
          {
              private string _name;
      
              public string Name
              {
                  get
                  {
                      return _name;
                  }
                  set
                  {
                      _name = value;
                  }
              }
      
              public object[][] Data { get; set; }
          }
      

      抽象类中的相同场景

          public abstract class MyAbstractClass
          {
              public abstract string Name { get; set; }
              public abstract object[][] Data { get; set; }
          }
      
          private class MyImpl : MyAbstractClass
          {
              public override string Name { get; set; }
              public override object[][] Data { get; set; }
          }
      
          private class MyImplBacked : MyAbstractClass
          {
              private string _name;
      
              public override string Name
              {
                  get
                  {
                      return _name;
                  }
                  set
                  {
                      _name = value;
                  }
              }
      
              public override object[][] Data { get; set; }
          }
      

      【讨论】:

        猜你喜欢
        • 2012-10-22
        • 2011-01-09
        • 2019-01-09
        • 1970-01-01
        • 2011-01-19
        • 1970-01-01
        • 2017-02-19
        • 1970-01-01
        • 2014-04-12
        相关资源
        最近更新 更多