1

Say I have the following code:

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

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

Is it at all possible for there to be different behavior between:

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

and:

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

?

JoelFan
  • 37,465
  • 35
  • 132
  • 205
  • 1
    Given the example you've shown above, no. Assuming the signature of `someMethod` takes an `IFoo` – Dave Zych Dec 05 '12 at 20:35
  • It shouldn't be possible with an interface, no. (As opposed to abstract/virtual classes/members and other such inheritance concepts.) Have you noticed behavior which demonstrates that it can be different? Or is this mainly an idle curiosity? – David Dec 05 '12 at 20:36
  • Well the problem I'm seeing is more complicated but I think essentially the only difference is whether it's declared by class or by interface, and it's behaving differently. – JoelFan Dec 05 '12 at 20:36
  • 2
    If you have two overloaded versions of someMethod where one takes Foo and the other IFoo, then you could have it doing two different things. – juharr Dec 05 '12 at 20:38
  • 2
    Can you provide a short but complete example of the problem? There is no distinguishable difference in the examples you've given, and I'm sure someone can spot what's going on pretty easily if we have a more complete example. – Dave Zych Dec 05 '12 at 20:44

8 Answers8

4

I think it may differ. If somebody's used bad style of programming, i.e.:

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
    Keep in mind this isn't *entirely* a bad practice. For example, LINQ does this all the time. When the concrete type is actually an `ICollection` it can perform many of the operations much more efficiently by doing this, without changing the end result. It also make it invisible to the caller (beyond being faster). – Servy Dec 05 '12 at 22:12
  • Yes, sure, if it's necessary, then can be used. The main thing is to have the right hands/head.) – Andrey Evseenko Dec 06 '12 at 10:55
  • But it's not necessary, that's actually my point. It's purely a performance optimization. The important point is that it's invisible to the user of the method, and that the writer/maintainer is willing to pay the price of higher internal complexity and maintenance costs in exchange for whatever advantages it's providing. – Servy Dec 06 '12 at 14:55
3

Yes, there is a difference if someMethod has different overloads for IFoo and Foo.

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
user703016
  • 37,307
  • 8
  • 87
  • 112
  • 1
    This could get even more subtle if the method in question is an extension method, making it _appear_ that the behavior is on the object itself. – David Dec 05 '12 at 20:44
1

(I'm no expert) but in your first scenario, you would get access to everything in Class Foo. In the second scenario, you would only be able to access the IFoo members. So if Foo has additional methods (that aren't part of the interface), you will be able to access them in your first scenario but not the second.

I believe using the interface name instead of the class name is just another way to encapsulate data and only provide access to the interface members. For instance you could have Foo and Bar which both implements IFoo. You could add both of them to, say, a List.

Joe
  • 2,496
  • 1
  • 22
  • 30
  • OK but if `someMethod` would take advantage of other memebers then it would not compile if the interface was used. In my case it's compiling and running for both, just giving different results – JoelFan Dec 05 '12 at 20:37
  • You did not mention what someMethod accepts as argument. If it accepts IFoo, both will work. If it needs Foo, the second scenario will fail to compile. – Joe Dec 05 '12 at 20:39
  • Also I believe your comment is slightly wrong. The interface implementation will always be done in the class and never within the interface. So even if you're passing Foo or Bar, if someMethod needs an IFoo, both should work and both will use their specific implementation of the interface (ref: taking advantage of other members) – Joe Dec 05 '12 at 20:43
1

There would never be any difference.

Remember, an interface is a contract. By deriving Foo from IFoo, you are implementing that contract.

In both cases, because Foo is an IFoo and adheres to the contract, the behaviour will always be the same.

Of course, how Foo implements that contract is anybodies guess. But the contract is adhered too by the signature of the interface.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
1

Different bahavior can be, but inside someMethod.

Say you have

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

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

if you have

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

Which will not be possible to do in case when the parameter of the method is defined like.

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

unless you don't cast. So the difference is that decaring IFoo, to decalre generic access parameter, but get less "potential" in terms of data access, but get a huge potential in abstraction over types in your architecture.

So the difference will be only in regard of architecture and program workflow.

Tigran
  • 61,654
  • 8
  • 86
  • 123
  • This example is of one compiling and one not... my case is both compile and both run, but give different behavior – JoelFan Dec 05 '12 at 20:41
  • @JoelFan: so you need abstraction, in this case. Just use `IFoo` like a parameter. – Tigran Dec 05 '12 at 20:53
1

If you have two interfaces and there is a common method name in each of them then the implementing class can implement the same method differently. The it depends how the method is called - via interface or not and via which interface.

See here for a similar question:

Inheritance from multiple interfaces with the same method name

Community
  • 1
  • 1
A.H.
  • 63,967
  • 15
  • 92
  • 126
1

You could have an explicitly implemented interface in Foo.

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

with this, you will have:

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

Console.WriteLine(foo1.fooProp); // Foo
Console.WriteLine(foo2.fooProp); // iFoo
Paolo Falabella
  • 24,914
  • 3
  • 72
  • 86
0

It's possible if you explicitly implement 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));
}
Lee
  • 142,018
  • 20
  • 234
  • 287