为什么我可以更改类中接口中定义的属性的实现

时间:2015-05-29 13:30:15

标签: c# .net oop interface

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

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




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

        public void changeValue()
        {
        }
    }

4 个答案:

答案 0 :(得分:2)

假设你有

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函数也是如此。编译器不反对。这正是你在原始例子中所做的。

答案 1 :(得分:0)

如果要更改类中的值,则应添加私有设置器:

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

您无法更改界面成员的行为。这是一个必须遵守的合同。

答案 2 :(得分:0)

如果您正在做类似

的事情
import struct

V4_HEADER_SIZE = 108
COLOR_INFO_SIZE = 68
HEADER_OFF = 14
DATA_OFF_FIELD = 10
SIZE_OFF  =  2
def strip_color_info(old_bmp_name, new_bmp_name=None):
    if new_bmp_name is None:
        new_bmp_name = old_bmp_name
    data = bytearray(open(old_bmp_name, "rb").read())
    header_size = struct.unpack("I", data[HEADER_OFF: HEADER_OFF + 4])[0]
    if header_size == 108:
        # Remove 68  - the size for the extra data-chunk from both headers
        data[HEADER_OFF: HEADER_OFF + 4] = struct.pack("I", V4_HEADER_SIZE - COLOR_INFO_SIZE)
        data[DATA_OFF_FIELD: DATA_OFF_FIELD + 4] = struct.pack("I",
            struct.unpack("I",data[DATA_OFF_FIELD: DATA_OFF_FIELD + 4])[0] - COLOR_INFO_SIZE)
        # Offset image data:
        data[HEADER_OFF + header_size - COLOR_INFO_SIZE:] =  data[HEADER_OFF + header_size:]
        data[SIZE_OFF: SIZE_OFF + 4] = struct.pack("I", len(data))
    with open(new_bmp_name, "wb") as output_file:
        output_file.write(data)

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

ITest test = new Test();

答案 3 :(得分:0)

所有接口都声明任何实现类都会执行的最低限度。这是一个合同,"实现此接口的每个类型都将具有这些属性和方法。"它完全将实现类限制为接口上定义的方法和属性。

例如,如果您有一个实现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<T>

因此,使用您的示例界面,您所说的就是&#34;如果您在此界面上操作,那么您所能做的就是获取{{{ 1}}#&34;

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

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; } } 上工作,或者返工界面。但是如果你不需要使用setter,那么界面上缺少一个就可以用于定义。