C# - Interface setting property to { get, set } another interface - c#

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.

Related

How to make the interface enforce the implementation not having a setter?

following the example:
interface ISomeInterface
{
string SomeProperty { get; }
}
I have the implementation that compiles:
public class SomeClass : ISomeInterface
{
public string SomeProperty
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
which is a problem. How do I make the interface a contract that, won't allow set in it's implementation?
notice: I'm not looking for a solution how to avoid set IN the implementation but in the interface that will validate it from any new implementation, thanks.
Interfaces only specify what MUST be implemented, but do not restrict what other methods, or properties may also be implemented.
So the get is the only thing that you have specified.
Since you are silent on the set, any implementer of the interface is at liberty to add or not to add the set.
In short, with an interface specification you cannot do what you want to do.
If you want to make sure the set is never called then you could always cast the instance to the Interface
If you really need to make sure there is no set you could use an abstract class instead of an interface
abstract class SomeInterface
{
virtual string SomeProperty { get; }
}
Based on Mike answer, you could write something like that :
public interface ISomeInterface
{
string SomeProperty { get; }
}
public abstract class SomeInterfaceBase : ISomeInterface
{
public abstract string SomeProperty { get; }
}
So you can define your class like that:
public class SomeClass : SomeInterfaceBase
{
public override string SomeProperty { get; }
}
If you try to implement a setter, it will not compile.
Having a setter isn't an issue. The reason for this is because of how we treat interfaces.
Whether the concrete class has a setter or not does not matter, because we are supposed to treat the object as an ISomeInterface. In this case it only has a setter.
For instance lets take a factory method:
class Program
{
interface ISomeInterface
{
string SomeProperty { get; }
}
static ISomeInterface CreateSomeClass()
{
return new SomeClass();
}
class SomeClass : ISomeInterface
{
public string SomeProperty
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
static void Main(string[] args)
{
ISomeInterface someInterface = CreateSomeClass();
someInterface.SomeProperty = "test"; //Wont compile
}
}
The class's implementation of a setter is meaningless, because we are only interested in treating the object as ISomeInterface. Interfaces are additive. In other words, they define a contract of what needs to be defined, rather than what should not.
If I was to treat it in any other way, it would be something like this:
((SomeClass) someInterface).SomeProperty = "test"; //Code smell
which I would consider a code smell, because it's assuming that someInterface is SomeClass (treating interfaces as concrete classes)

Can you model an interface where only it's descendants can be implemented?

Assume the following code:
namespace Example {
public interface IBase {
string CommonMember { get; set; }
}
public interface IDerived : IBase {
void DoSomething();
}
public interface IComplexDerived : IBase {
IEnumerable<object> Junk { get; }
}
}
I have a similar structure in the project I'm currently working on. The interface IBase primarily serves the purpose to be able to keep instances of IDerived and IComplexDerived in the same container (like a List<IBase>) and also not having to repeat common interface member definitions (like CommonMember in the example).
One way this would then be used would be something like this:
public class Foo {
public void Bar( IEnumerable<IBase> instances ) {
foreach( IBase instance in instances ) {
if( instance is IDerived ) { /* do something */ }
else if( instance is IComplexDerived ) { /* do something else */ }
}
}
}
So, nothing would stop the user from implementing IBase and passing instances of that class into the system. But doing that would be completely useless because the whole library only expects to deal with classes that implement interfaces that were derived from IBase.
This concept is of course fully documented and shouldn't cause any problems. However, I was wondering if it would be possible to communicate this through means of the language itself. Like having an abstract class, but for interfaces.
You might ask why not simply use an abstract class then. The reason for that is that we don't want to impose the requirement to inherit from our class.
I'm not sure if this is feasible in your actual case, but I think you could have
IComplexDerived inherit from IDerived instead of IBase.
You would then have a list of IDerived instead of IBase, so even a new implementation of IBase would not type-check (since you require an IEnumerable<IDerived>)
Your classes inheriting from IComplexDerived would simply implement DoSomething() in a different way. By doing this you would let your Bar method decide polymorphically what DoSomething it needs to call (and avoid checking on the type)
I mean something like this:
public interface IBase {
string CommonMember { get; set; }
}
public interface IDerived : IBase {
void DoSomething();
}
//IComplexDerived isnow a IDerived
public interface IComplexDerived : IDerived {
IEnumerable<object> Junk { get; }
}
public class Foo
{
// Bar requires IEnumerable<IDerived> so you can't call it with a collection
// of classes implementing IBase
public void Bar( IEnumerable<IDerived> instances ) {
foreach( IDerived instance in instances ) {
instance.DoSomething(); // DoSomething will "do something else" in
// classes implementing IComplexDerived
}
}
}
One possibility is to remove the common interface from IDerived and IComplexDervied and create a wrapper class which takes an instance of one of them and provides the common functionality:
public interface IDerived
{
void DoSomething();
string CommonMember { get; set; }
}
public interface IComplexDerived
{
IEnumerable<object> Junk { get; }
string CommonMember { get; set; }
}
public class EitherDerived : IBase
{
private readonly IDerived derived;
private readonly IComplexDerived complex;
private readonly bool isComplex;
public EitherDerived(IDerived derived)
{
this.derived = derived;
this.isComplex = false;
}
public EitherDerived(IComplexDerived complex)
{
this.complext = complex;
this.isComplex = true;
}
public string CommonMember
{
get
{
return isComplex ? complex.CommonMember : derived.CommonMember;
}
set
{
//...
}
}
public TOut Either<TOut>(Func<IDerived, TOut> mapDerived, Func<IComplexDerived, TOut> mapComplex)
{
return isComplex ? mapComplex(complex) : mapDerived(derived);
}
}
Then you can use this class instead of your IBase interface if you want to be sure you are dealing with one of those classes:
private object HandleDerived(IDerived derived) { ... }
private object HandleComplex(IComplexDerived complex) { ... }
public void Bar(IEnumerable<EitherDerived> instances)
{
foreach(var either in instances)
{
object _ = either.SelectEither(HandleDerived, HandleComplex);
}
}
The suggestion to look for a different design altogether was what I ended up doing. Since this is an open source project, we can look at the actual results.
IBase is ITimelineTrackBase and describes interface members that are common to all derived types.
IDerived is ITimelineTrack and it describes a track on a timeline which consists of a single element with a start and end.
IComplexDerived is IMultiPartTimelineTrack and it describes a track on a timeline which consists of multiple elements that each have a start and an end.
Contrary to my earlier plans, I'm not storing these in a List<IBase>, but I'm using List<IComplexDerived>. Or, in terms of the application, a List<IMultiPartTimelineTrack>.
Now I decided to not accept an IBase anywhere if that's not what I actually want to support in that method. So the ITimelineTrackBase is used purely as a base interface and isn't offered as an accepted parameter type anywhere in the library.
Instead the whole library deals either with single track elements (ITimelineTrack) or a collection of those (IMultiPartTimelineTrack). As needed, the former is wrapped into the latter by a helper construct SingleTrackToMultiTrackWrapper.
So instead of making it impossible to implement the interface, I just made it pointless to implement it.

Is there any way an interface can cause different behavior?

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

Two way reference with interfaces and generics

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

Adding setters to properties in overrides

Why is it allowed to change the visibility and existence of getters or setters in a property when implementing an interface?
interface IFoo
{
string Bar { get; }
}
class RealFoo : IFoo
{
public RealFoo(string bar)
{
this.Bar = bar;
}
public string Bar { get; private set; }
}
class StubFoo : IFoo
{
public string Bar { get; set; }
}
...and not legal to do the same when implementing an abstract class?
abstract class AbstractFoo : IFoo
{
public abstract string Bar { get; }
}
class RealFoo : AbstractFoo
{
public RealFoo(string bar)
{
this.Bar = bar;
}
// Cannot override because 'Bar' does not have an overridable set accessor
public override string Bar { get; private set; }
}
The interface declares what public properties the class must have (It's just a contract). Which means you need to have those properties, but can add to them.
The abstract class declares the actual structure of those properties. So if you don't have the setter in the abstract base, you can't add to it in the implementation.
When you write the override modifier it looks in the base class for something to override.
It perhaps becomes clearer if you think of the getters and setters as the methods that they eventually become.
In the case of the interface you are defining this:
interface IFoo
{
string GetBar();
}
Which can be read as "all classes that implement this interface must include this method."
Both of your classes do:
class RealFoo : IFoo
{
public string GetBar();
private void SetBar(string value);
}
they also implement SetBar(), but that is immaterial; they have fulfilled the contract defined by the interface and are valid.
The abstract class, on the other hand is this:
abstract class AbstractFoo : IFoo
{
public abstract string GetBar();
}
Which means that all child classes must provide a method body for GetBar()
The class you made is this:
class RealFoo : AbstractFoo
{
public override string GetBar();
public override void SetBar(string value);
}
By putting the override modifier in front of the SetBar method the compiler is expecting to find an abstract or virtual version in the base class. You don't have that so the compilation fails.
An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes.
An interface, by contrast, is a totally abstract set of members that can be thought of as defining a contract for conduct. The implementation of an interface is left completely to the developer.
Taken from the MSDN
http://msdn.microsoft.com/en-us/library/scsyfw1d(v=VS.71).aspx
According to the C# specification
An accessor that is used to implement
an interface may not have an
accessor-modifier. If only one
accessor is used to implement an
interface, the other accessor may be
declared with an accessor-modifier:
public interface I
{
string Prop { get; }
}
public class C: I
{
public Prop {
get { return "April"; } // Must not have a modifier here
internal set {...} // Ok, because I.Prop has no set accessor
}
}
That means it is OK to have an access modified on a class implementing the interface. However, the abstract class declares an implementation and you cannot change that with a derived class.

Categories

Resources