2012-12-05 39 views
1

说我有下面的代码:接口是否有任何方式可以导致不同的行为?

class Foo: IFoo { 
    public string fooProp { get; set; } 
} 

interface IFoo { 
    string fooProp {get; set; } 
} 

是它在所有可能的那里是之间不同的行为:

Foo x = new Foo(); 
someMethod(x); 

和:

IFoo x = new Foo(); 
someMethod(x); 

+1

鉴于你上面显示的例子,没有。假设'someMethod'的签名需要一个'IFoo' –

+0

接口不应该可以,no。 (与抽象/虚拟类/成员以及其他这样的继承概念相对)。你注意到行为表明它可能有所不同吗?或者这主要是一种闲置的好奇心? – David

+0

嗯,我看到的问题更复杂,但我认为唯一的区别是它是由类或接口声明的,它的行为有所不同。 – JoelFan

回答

1

(我不是专家),但在第一种情况下,您可以访问Foo类中的所有内容。在第二种情况下,您只能访问IFoo会员。因此,如果Foo具有其他方法(不属于界面的一部分),则可以在第一种情况下访问它们,但不能在第二种情况下访问它们。

我相信使用接口名称而不是类名只是封装数据的另一种方式,只能提供对接口成员的访问。例如,你可以有两个都实现IFoo的Foo和Bar。您可以将它们都添加到列表中。

+0

好的,但如果'someMethod'会利用其他成员,那么如果使用该接口它将不会编译。在我的情况下,它正在编译和运行,只是给出不同的结果 – JoelFan

+0

你没有提到someMethod接受什么作为参数。如果它接受IFoo,两者都可以工作。如果它需要Foo,则第二种情况将无法编译。 – Joe

+0

另外我相信你的评论有些不对。接口实现将始终在类中完成,永远不会在接口中完成。所以即使你传递了Foo或Bar,如果某个方法需要一个IFoo,两者都应该工作,并且两者都将使用它们的接口的具体实现(参考:利用其他成员) – Joe

1

永远不会有任何区别。

请记住,一个接口是合同。通过从IFoo推导Foo,您正在实施合同

在这两种情况下,由于FooIFoo并遵守合同的,该行为将始终是相同的。

当然,如何 Foo实现该合同是任何机构的猜测。但是通过界面的签名也符合合同。

1

不同的行为可以是,但在someMethod里面。

说你有

class Foo: IFoo { 
    public fooProp { get; set; } 
} 

interface IFoo { 
    fooProp {get; set; } 
    myCustomProp {get;set} 
} 

,如果你有

public void someMethod(Foo _foo){ 
    _foo.myCustomProp; //CAN DO THIS, AS YOUR TYPE IS _FOO_ 
} 

该不会是可能的情况下办时,方法的参数等规定。

public void someMethod(IFoo _foo){ 
    _foo.myCustomProp; //NO SUCH METHOD INFO 
} 

除非你不投。所以区别在于,IFoo拒绝了通用访问参数,但在数据访问方面获得的“潜在”更少,但是在您的体系结构中对类型进行抽象的可能性很大。

所以差异将只在架构和程序工作流程。

+0

这个例子是一个编译而不是一个编译。 ..我的情况是既编译和运行,但给不同的行为 – JoelFan

+0

@JoelFan:所以你需要抽象,在这种情况下。只需使用“IFoo”就像一个参数。 – Tigran

3

是的,是有区别的,如果someMethodIFooFoo不同的重载。

public void someMethod(Foo f) 
{ 
    // Overload 1 
} 

public void someMethod(IFoo f) 
{ 
    // Overload 2 
} 

Foo x = new Foo(); 
someMethod(x); // Matches overload 1 
IFoo x = new Foo(); 
someMethod(x); // Matches overload 2 
+1

如果所讨论的方法是一个扩展方法,这可能会变得更加微妙,使它看起来就是该行为在对象本身上。 – David

1

如果您有两个接口,并且每个接口都有一个公共方法名,那么实现类可以以不同的方式实现相同的方法。它取决于如何调用方法 - 通过接口或不通过哪个接口。

在这里看到一个类似的问题:

Inheritance from multiple interfaces with the same method name

1

你可以在美孚的明确实现的接口。

class Foo: IFoo { 
    private string _fooprop; 
    private string _ifooprop; 

    public string fooProp  
    { 
     get {return "IFoo";} 
     set {_fooprop=value;} 
    } 
    string IFoo.fooProp 
    { 
     get {return "Foo";} 
     set {_ifooprop=value;} 
    } 
} 

interface IFoo { 
    string fooProp {get; set; } 
} 

这一点,你将有:

IFoo foo1=new Foo(); 
Foo foo2=new Foo(); 

Console.WriteLine(foo1.fooProp); // Foo 
Console.WriteLine(foo2.fooProp); // iFoo 
0

,如果你明确实现IFoo这是可能的:

public class Foo : IFoo 
{ 
    public string Prop 
    { 
     get { return "Hello Foo"; } 
    } 

    string IFoo.Prop 
    { 
     get { return "Hello IFoo"; } 
    } 
} 

public static void SomeMethod<T>(T foo) where T : IFoo 
{ 
    var prop = typeof(T).GetProperty("Prop"); 
    Console.WriteLine(prop.GetValue(foo)); 
} 
4

我认为它可能会有所不同。如果有人使用了不好的编程风格,例如:

public void someMethod(IFoo f) 
{ 
    if (f is Foo) 
    { 
     Foo f1 = (Foo)f; 
     //Do smth with unique Foo members 
    } 
    //Do anything with IFoo members 
} 
+1

请记住,这不是一个坏习惯。例如,LINQ一直这样做。当具体类型实际上是一个'ICollection'时,它可以通过这样做更有效地执行许多操作,而不会改变最终结果。它也使它对呼叫者不可见(除了更快)。 – Servy

+0

是的,当然,如果有必要,那么可以使用。主要的是要有正确的手/头。) –

+0

但这不是必要的,那实际上是我的观点。这纯粹是性能优化。重要的一点是,这种方法的用户是看不见的,作者/维护人员愿意付出更高内部复杂性和维护成本的代价,以换取其提供的任何优势。 – Servy

相关问题