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);
?
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
}
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
(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.
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.
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
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.
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
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));
}
Related
How do I get the implemented Name from FooImpl from either the interface IFoo or an instance object?
public interface IFoo {
static abstract string Name { get; }
}
public class FooImpl : IFoo {
public static string Name => "Foo";
}
I can't seem to get the Name value from these methods. Am I missing something? Note that I'd like to access the Name from any implementation of IFoo without knowing the implementation being used. As such, FooImpl.Name would compile and run, but it is not what I'm looking to do directly.
IFoo anImpl = new FooImpl();
Console.WriteLine(anImpl.Name); // [CS0176] Member 'IFoo.Name' cannot be accessed with an instance reference; qualify it with a type name instead
// I know this won't work
Console.WriteLine(IFoo.Name); // [CS8926] A static virtual or abstract interface member can be accessed only on a type parameter.
static string GetName<T>() where T : IFoo
{
return T.Name;
}
// I know this won't work
Console.WriteLine(GetName<IFoo>()); // [CS8920] The interface 'IFoo' cannot be used as type argument. Static member 'IFoo.Name.get' does not have a most specific implementation in the interface.
static string GetName2<T>(T implementation) where T : IFoo
{
return T.Name;
}
Console.WriteLine(GetName2(anImpl)); // [CS8920] The interface 'IFoo' cannot be used as type argument. Static member 'IFoo.Name.get' does not have a most specific implementation in the interface.
I'm not sure what else to try. This post is related but I don't see an answer other than reflection.
Note that I'd like to access the Name from any implementation of IFoo without knowing the implementation being used
Yes, this is impossible (other then with reflection). Static abstract interface members as any other static members belong to type, not to instance so they can be retrieved only via type. You can use the solution from the linked answer or call the GetName "dynamically" i.e. something like:
var fooName = typeof(...).GetMethod(nameof(....GetName))
.MakeGenericMethod(anImpl.GetType())
.Invoke(null, null);
Also you can wrap either of the approaches in some helper and store the processed types values into Dictionary<Type, string> (or ConcurrentDictionary) to mitigate the reflection cost. Or even prebuild the dictionary (depends on the use case).
There is another approach but it requires some changes to the type hierarchy. You can use curiously recurring template pattern (CRTP) + extra method + extra generic interface with default method implementation:
public interface IFoo {
static abstract string Name { get; }
public string GetName();
}
public interface IFoo<T> : IFoo where T : IFoo<T> // CRTP
{
string IFoo.GetName() => T.Name;
}
public class FooImpl : IFoo<FooImpl> {
public static string Name => "Foo";
}
And usage:
IFoo anImpl = new FooImpl();
Console.WriteLine(anImpl.GetName());
You implement it with a read-only property and assign a default value to it.
public interface IFoo {
static abstract string Name { get; }
}
public class FooImpl : IFoo {
public static string Name {get; } = "Foo";
}
Then you read the value where consumed as
public void DoStuff<T>() where T : IFoo
{
string name = T.Name;
}
or specific implementation
public void DoStuff()
{
string name = FooImpl.Name;
}
Please consider the following program:
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
public void DoFoo() => Console.WriteLine("BAR!");
}
public class Baz: Bar, IFoo
{
void IFoo.DoFoo() => Console.WriteLine("baz!");
}
class Program
{
static void Main()
{
Baz baz = new Baz();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
Bar bar = baz;
bar.DoFoo();
IFoo foobar = bar;
foobar.DoFoo();
}
}
It gives the following output which I personally with my C++ background consider highly unexpected:
BAR!
baz!
BAR!
baz!
Having , IFoo in the declaration of Baz seems to be substantial, because otherwise void IFoo.DoFoo() doesn't compile.
Can someone please explain what is going on here (especially the last line)? And what should be done to prevent such behavior in real life? Should one avoid implementing from the same interface at all or there are some other rules to avoid problems?
UPD:
Looks like the principal problem here is not with "multiple inheritance" (which is not real multiple inheritance actually), but with the way interface methods can be implemented in C#. Namely, one can have two different implementations of the same method in the same class, one of which is explicit, another is implicit. E.g. this program:
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
void IFoo.DoFoo() => Console.WriteLine("Foo!");
public void DoFoo() => Console.WriteLine("BAR!");
}
class Program
{
static void Main()
{
Bar baz = new Bar();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
}
}
prints
BAR!
Foo!
The trick with "multiple inheritance" just allows to introduce the explicit implementation from a derived class.
From my point of view this feature of C# is potentially dangerous, because if one implements a method of an interface, one usually expects the same method will be called no matter if it is invoked from the interface or from the class. And this is really the case if one implements everything only explicitly or only implicitly. But if both ways are used, this assumption is broken. So the moral seems to be:
Don't mix implicit and explicit implementation of the same method if you don't have in mind to employ this strange effect for some purpose.
Use explicit implementation in derived classes with caution.
This is a difference in the explicit implementation (void IFoo.DoFoo()) vs the implicit implementation (public void DoFoo()). The compiler will use the explicit implementation first. If you provide both an explicit and implicit implementation then the difference becomes clear:
https://dotnetfiddle.net/7l9gIs
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
public void DoFoo(){ Console.WriteLine("BAR!"); }
}
public class Baz: Bar, IFoo
{
void IFoo.DoFoo(){ Console.WriteLine("baz explicit!"); }
public new void DoFoo(){ Console.WriteLine("baz implicit!"); }
}
public class Program
{
public static void Main()
{
Baz baz = new Baz();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
Bar bar = baz;
bar.DoFoo();
IFoo foobar = bar;
foobar.DoFoo();
}
}
Output
baz implicit!
baz explicit!
BAR!
baz explicit!
Implicit implementations tend to be more common and more convenient for usage. They are less verbose and any usage of the concrete type will have the implementations of the members exposed. Implicit implementations don't include the name of the interface being implemented before the member name, so the compiler infers this. The members will be exposed as public and will be accessible when the object is cast as the concrete type.
Visit this link for more details https://www.pluralsight.com/guides/distinguish-explicit-and-implicit-interface-implementation-csharp
The confusion is starting when you implement Baz from IFoo. Because Bar is already implements IFoo and Baz is the subclass of Bar. So, you dont need to do that.
In object oriented programming its not a best practice, in fact it is worst practice.
If you want to override DoFoo method, use the following code
public interface IFoo
{
void DoFoo();
}
public class Bar : IFoo
{
public virtual void DoFoo()
{
// do something
}
}
public class Baz : Bar
{
public override void DoFoo()
{
// override what you did in Bar class
}
}
In your code, when you try to baz.DoFoo, in fact you are calling bar.DoFoo.Because you didnt override it. Its the problem.
So, I was writing two interfaces on the following structure:
public interface IBar
{
string DoStuff();
}
public interface IFoo
{
IBar Bar { get; set; }
}
On my implementation of IFoo, I have to do things like:
public class FooImpl : IFoo
{
private BarImpl _barImpl;
public IBar Bar
{
get { return _barImpl }
set { _barImpl = (BarImpl) value }
}
}
And then I will always have to be casting things around while using it, unless I manage some implicit operator which I don't want to.
So, is there a better way to write this in order to not cast things around and maybe have a clean Property { get; set; } on my implementations?
EDIT
Just to clarify why I (think) I need it this way: Let's say on my FooImpl I will need specific methods of BarImpl to work with. But DoStuff(), which are common to all IBars may be called from another places like fooImpl.Bar.DoStuff(). Does that make sense?
Thanks!
How about to use a generic interface? Try this code:
public interface IFoo<T> where T : IBar
{
T Bar { get; set; }
}
public class FooImpl : IFoo<BarImpl>
{
private BarImpl _barImpl;
public BarImpl Bar
{
get { return _barImpl; }
set { _barImpl = value; }
}
}
I think you're approaching the concept of Interfaces the wrong way. In absolute, IFoo shouldn't require a specific implementation of IBar. In your IFoo implementation, remove the any reference to BarImpl and replace it with IBar.
If, for an extraordinary reason, FooImpl can only work with BarImpl, and no other implementations, then in your IoC registrations just set it that way. Can't guide you through that if I don't know which IoC container you're using. If you're not using IoC at all, you can just instantiate the proper type of IBar of course.
You can have a constructor there which takes object of IBar type parameter and pass the BarImpl from outside the class which will add loose coupling to it like:
public class FooImpl : IFoo
{
private IBar _barImpl;
public IBar Bar
{
get { return _barImpl }
set { _barImpl = value; }
}
public FooImpl(IBar bar)
{
_barImpl = bar;
}
}
and in this case you would want to make your IBar property read only so that it's can't be changed from outside, so just add getter in it like:
public IBar Bar
{
get { return _barImpl; }
}
This way your FooImpl only knows about the interface and is not tightly bound with the implementation of the IBar and any implementation could be passed from outside.
Now when creating instance of FooImpl you will have to pass the BarImpl as parameter :
BarImpl bar = new BarImpl();
var foo = new FooImpl(bar);
Hope it helps!
One option is to use an explicit interface implementation:
public class FooImpl : IFoo
{
private BarImpl _barImpl;
public BarImpl Bar
{
get { return _barImpl; }
set { _barImpl = value; }
}
IBar IFoo.Bar
{
get { return _barImpl; }
set { _barImpl = (BarImpl)value; }
}
}
In this case, any time you are working with an object of type FooImpl, the Bar property will return a BarImpl type, removing the need to cast it in calling code. However, the class still implements IFoo properly and will return an IBar reference in any context where it is used as an IFoo reference.
This implementation becomes even cleaner if you can change IFoo.Bar to be read-only and instead require IFoo implementers to get their IBar member through a constructor or other means. This allows a FooImpl to require a BarImpl implementation of IBar without casting in the IFoo.Bar setter.
Here's my best attempt to recreate the situation.
public interface IFoo
{
}
public class Foo : IFoo { }
public class Bar : IFoo { }
public class CollectionOf<T> : List<IFoo>
{
}
public class Bars : CollectionOf<Bar>
{
}
public class Test
{
public void Test()
{
CollectionOf<IFoo> bars = new Bars();
}
}
Compiler complains on the instantiation. Bars is a collection of IFoos. Is this one of those covariance/contravariance issues?
Yes.
Think about it for a second; bars should legally be able to hold objects of any type that implement IFoo. However, an object of type Bars can only hold objects of type Bar.
Using your code this would be allowed, which is obviously wrong.
CollectionOf<IFoo> bars = new Bars();
bars.Add( new Foo() ); // Uh oh!
That would effectively break the type safety afforded to you via generics.
Yes it is.
If this was allowed, you would be able to place any object into that collection, as long as it implemented the IFoo interface, but that wouldn't be safe for the collection.
Let me illustrate:
var b = new Bars();
CollectionOf<IFoo> bars = b;
bars.Add(Dummy); // implements IFoo, but does not descend from Bar
At this point, what does b contain? An object of type Dummy? That would be bad, and thus this is not allowed in the first place.
The fix, if there is one would depend on what it is that's not working for you. I can get your example to compile in two ways, either use IEnumerable or define your CollectionOf as an interface with the out generic modifier. Whether either is a fix for you I don't know:
public interface IFoo { }
public class Foo : IFoo { }
public class Bar : IFoo { }
public interface CollectionOf<out T> : IEnumerable<IFoo> { }
public class Bars : CollectionOf<Bar> { }
public class Test
{
public void Test()
{
IEnumerable<IFoo> bars1 = new Bars();
CollectionOf<IFoo> bars2 = new Bars();
}
}
I've got a class with generics which uses another class, which in return needs to know what instance of the initial class "owns" it - which causes problems ;) Let me give an example:
public interface IFoo<T>
{
}
public interface IBar
{
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new()
{
private readonly T _bar;
public Foo()
{
_bar = new T {Foo = this};
}
}
class Bar : IBar
{
public IFoo<IBar> Foo { get; set; }
}
This doesn't work as Foo = this doesn't work - even if I try to cast this to IFoo (compiles but fails at run time). I've tried to tweak the code various ways, but I've not found an implementation that works...
Hopefully you see what I'm trying to do, and perhaps you even see how I can achieve this ;-)
You can solve this with a combination of an explicit cast in the constructor, along with c#4.0 support for covariance on generic parameters.
First, you need to insert a cast in the Foo<T> constructor:
_bar = new T {Foo = (IFoo<IBar>)this};
Just doing that isn't sufficient, though. Your constraint that T : new() means that T needs to be a concrete class. As such, IFoo<T> will never be exactly IFoo<IBar>. However, if you specify that the generic parameter T for IBar<T> is covariant, then the cast from IFoo<Bar> to IFoo<IBar> will become legal:
public interface IFoo<out T>
The out keyword specifies that the parameter is covariant (which essentially means "this parameter will only be output by methods, never input.")
This MSDN article offers more details on covariance and contravariance.
Would declaring the T type parameter of IFoo as covariant solve your problem?
This code should allow you to do what you are trying:
public interface IFoo<out T> {
}
public interface IBar {
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new() {
private readonly T _bar;
public Foo() {
_bar = new T { Foo = (IFoo<IBar>)this };
}
}
class Bar : IBar {
public IFoo<IBar> Foo { get; set; }
}
public static class Program {
public static void Main(params string[] args) {
Bar b = new Bar();
Foo<Bar> f = new Foo<Bar>();
}
}