Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 接口中的属性_C#_.net_Oop_Properties_Interface - Fatal编程技术网

C# 接口中的属性

C# 接口中的属性,c#,.net,oop,properties,interface,C#,.net,Oop,Properties,Interface,在我的接口中,我用setter和getter声明了一个属性 public interface ITestInterface { string AProperty { get; set; } } 当我编写继承该接口的类时,为什么需要再次定义这两个属性 public sealed class MyClass: ITestInterface { public string AProperty { get; set; } } 因为您不是从接口继承,所以您是在实现接口。(尽管它们都使用相同

在我的接口中,我用setter和getter声明了一个属性

public interface ITestInterface
{
   string AProperty { get; set; }
}
当我编写继承该接口的类时,为什么需要再次定义这两个属性

public sealed class MyClass: ITestInterface
{
   public string AProperty { get; set; }
}

因为您不是从接口继承,所以您是在实现接口。(尽管它们都使用相同的语法


假设您继承了一个糖果盒(不是从您的祖先那里,以编程方式),它(不是完全)像您将糖果盒放在另一个盒子中一样,现在外部盒子(派生类,继承类)是从糖果盒继承的,并且拥有糖果盒拥有的所有东西,但是如果您想要实现(make)你必须自己做一个盒子,放一些糖果在里面。这是接口的工作方式。

接口包含属性签名,而不是实际定义。实际上,您正在请求任何实现ITestInterface的类实现get和set for AProperty。有关更多详细信息,请参阅和。

您的接口定义只告诉您有一个带有getter和setter的属性,而不是它是如何实现的。您可以使用自动实现的属性,但不需要这样做

按照接口,这将是一个有效的实现:

public sealed class MyClass: ITestInterface
{
    public string APROPERTY
    {
        get { return someField + " hello"; }
        set { someOtherField = value; }
    }
}

在接口定义中,
string AProperty{get;set;}
是属性的声明,而在类中,这意味着属性是自动实现的。

我认为这里的问题是,相同的语法对接口和类有两种不同的含义
AProperty{get;set;}
在接口中仅是声明,在类中是自动实现的接口

所以这个术语取决于上下文

public interface ITestInterface
{
    string AProperty { get; set; }
}
声明属性,但无法实现它

public sealed class MyClass: ITestInterface
{
    public string AProperty { get; set; }
}

实现接口,在接口中自动实现属性(仅适用于类)。

正如其他人所说,接口只是方法和属性签名的容器。它需要实现,但此实现签名将与接口中使用的签名完全匹配。此外,它还保证所有这些成员都可以在类实例中访问,因为它们是默认的公共属性,并且没有实现程序就不会编译

假设您有一个接口:

public interface ITestInterface
{
    string AProperty { get; }
}
以及实现它的类:

class MyClass : ITestInterface
{
   public string AProperty { get { if (DateTime.Today.Day > 7) return "First week of month has past"; return "First week of month is on"; } }
}
无法使用自动实现的属性,也无法在此类中添加setter,因为接口属性缺少set访问器,并且自动实现的属性要求接口包含自动实现的属性签名({get;set;})。因此,在您的示例中,接口仅声明属性,仅此而已


只需知道类继承了哪些接口,您就知道存在哪些成员,并且如果您只想使用(或允许用户使用)这些方法中的某些方法(但不允许更改任何内容),您始终可以将类实例向上转换为这些接口类型之一,并将其作为参数传递。

简短回答

因为接口只包含类的定义,不能包含任何成员函数的实际实现。这是设计的

长答案

首先,您必须认识到属性基本上是带有一些简化语法的get和set成员函数。因此,这里的问题是:为什么接口定义不能包含成员函数的实现?

在某些语言中(最著名的是C++),您可以

如果你有一个继承链,那基本上是通过查找表来解决的。假设您有成员函数1,那么在继承链中的所有类中,都有一个表,其中包含指向函数1的指针。调用成员函数后,调用基本上会从属于对象类型的表中获取第一个条目,并调用该条目。这被称为vtable(有关更多详细信息,请参阅)

现在,在C++中,VTables对开发人员非常透明:每个类基本上都有一个VTABLE,没有真正的“接口”。这也意味着所有类都可以有实现和成员,比如字段。如果你有一个纯虚拟成员类(例如没有实现的函数),那么你就有C++的“接口”等价物。p> 在软件工程中,这些类通常被称为“接口”类,因为它们只包含正在发生的事情的定义,而不包含实际的实现。接口有一个很好的特性,即它们描述功能而不实际深入细节,因此可以在代码中设置“边界”。有很多这样的用例,包括(RPC)通信、许多设计模式等等

C++中,类可以从多个类(多重继承)派生出来,有和没有实现。此外,由于接口实际上更像是“抽象”类,而不像C#中的“接口”,这意味着您还可以在那里添加功能。因此,前面描述的vtable包含指向所有基类中函数的指针

当您开始向接口类添加功能时,就会出现此问题。首先,假设你有这样的东西(我会用C#的形式来做):

这里我们感兴趣的是,如果在
D
类中调用
Foo
,会发生什么。为此,我们必须为类
D
构造一个vtable。基本上,此vtable如下所示:

Foo() -> C::Foo()
class B : A { void Foo() {...} } // changed into an implementation
这意味着,如果您构造一个
D
的对象,并调用
Foo
,那么您将在
C
类型中调用
Foo
的实现:

var tmp = new D();
tmp.Foo(); // calls C::Foo()
当我们把B的定义改成这样时,它就变得更难了:

Foo() -> C::Foo()
class B : A { void Foo() {...} } // changed into an implementation
同样,我们尝试为类
D
构建vtable,结果出现了一个问题:

Foo() -> C::Foo() or B::Foo()???
我们面临的问题是他
public interface ITestInterface
{
   string GetAProperty();
}

public class MyClass : ITestInterface
{
    public string GetAProperty()
    {
        // Do work...
        return "Value";
    }
}