【问题标题】:Why can i change an implementation of property defined in interface in the class为什么我可以更改类中接口中定义的属性的实现
【发布时间】:2015-08-12 09:36:27
【问题描述】:

我试图理解,如果我创建一个接口 ITest,它定义了一个只有 getter 的属性版本。然后,当我在 Test 类中实现此接口时,我可以将属性的定义更改为 getter 和 setter。如何更改接口的实现,如下所示?

internal interface ITest
    {
         int MyProperty { get;}
        void changeValue();
    }




   public class Test : ITest
    {
        public int MyProperty
        {
            get;
            set;
        }

        public void changeValue()
        {
        }
    }

【问题讨论】:

  • 你仍然尊重接口 - 你有一个属性获取器。该界面也不排除您也添加一个 setter。
  • 为什么?如何?问题是什么?
  • 我同意 Blam,你的问题不清楚。 Could you try to clarify it a bit?
  • @Rob 我明白你想说的话。这意味着我们正在实现 getter,甚至用 setter 覆盖实现。这就是它起作用的原因。我说的对吗?
  • 接口定义了你必须拥有的,而不是你可以拥有的。如果接口有这种限制,那么您的类将能够在接口中定义方法,而您将无法创建自己的方法或属性,除非它们位于接口中。跨度>

标签: c# .net oop interface


【解决方案1】:

假设你有

interface ITest2
{
     int MyProperty_Get();
}

你可以用这个类实现这个接口并不奇怪

class Test2 : ITest2
{
    private int myProperty;
    public int MyProperty_Get()
    {
         return myProperty;
    }

    //Not in the interface..
    public void MyProperty_Set(int value)  
    {
         myProperty = value;
    }
}

您可以将set 函数添加到您的类实现中,即使接口中没有定义set 函数。编译器不反对。这正是您在原始示例中所做的。

【讨论】:

    【解决方案2】:

    如果你正在做类似的事情

    ITest test = new Test();
    

    您将无法公开访问 setter。如果您只想私下访问设置器,您可以使用:

    public class Test : ITest
    {
        public int MyProperty
        {
            get;
            private set;
        }
    
        public void changeValue(int value)
        {
            MyProperty = value;
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果你想改变一个类中的值,你应该添加私有 setter:

      internal interface ITest
      {
           int MyProperty { get;}
           void ChangeValue();
      }
      
      class MyClass : ITest
      {
          public int MyProperty { get; private set; }
      
          public void ChangeValue()
          {
              MyProperty = 1;
          }
      }
      

      记住:

      接口成员:

      int Property { get; }
      

      对于实施是正确的:

      public int Property { get; private set;}
      

      public int Property
      { 
          get
          { 
              return 1;
          }
      }
      

      您无法更改界面成员的行为。这是一个班级必须遵守的契约。

      【讨论】:

      • 但是我的问题是我应该不能改变接口提供的定义。编译器应该给出一个错误。但事实并非如此。为什么会这样?
      • setter 不必是私有的。您的类仍然可以超出接口的定义,并且该实现也可以提供公共设置器。你想让 setter 保持私有的唯一原因是你不希望它在类外可写。
      【解决方案4】:

      接口所做的只是声明任何实现类都会做的最低限度。这是一个约定,“实现此接口的每个类型都将具有这些属性和方法”。它确实将实现类限制为在接口上定义的方法和属性。

      例如,如果您有一个实现IDisposable 的类,您是否希望该类除了Dispose() 方法之外没有其他功能?

      当您将对象用作接口而不是具体类型时,接口定义了您可以对对象执行的操作:

      public int CountItems(IEnumerable<int> items)
      {
          return items.Count();
      }
      

      以上是一个非常简单的例子,但足以说明这一点。可以通过以下两个调用调用该方法:

      CountItems(new [] {1, 2, 3});
      CountItems(new List<int> {1, 2, 3});
      

      所有内部方法关心的是发送给它的对象是否暴露了Count()的Linq方法IEnumerable&lt;T&gt;

      因此,对于您的示例界面,您所说的只是“如果您在此界面上操作,您所能做的就是获得MyProperty 的值。”

      因此,所有这些类都是有效的:

      public void Test1 : ITest
      {
          public int MyProperty { get; private set; }
      
          public void changeValue() 
          {
              this.MyProperty = 12;
          }
      }
      
      public void Test2 : ITest
      {
          public int MyProperty { get; set; }
      
          public void changeValue()
          {
              this.MyProperty = 9;
          }
      }
      

      如果您尝试执行的操作需要在没有方法的情况下设置该值,那么您将不得不将该操作限制为仅在 Test2 上工作,或者重新设计接口。但是,如果您不需要使用 setter,那么界面上缺少 setter 就可以满足该定义。

      【讨论】:

        猜你喜欢
        • 2020-09-19
        • 1970-01-01
        • 2015-07-16
        • 1970-01-01
        • 2019-07-14
        • 2011-02-25
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        相关资源
        最近更新 更多