My example is a situation where the interfaces that inherit of the base interface need to add post conditions that are a result of their additional fields - the example occured when i decided to have an IInitialise interface as interfaces that inherit from this invariably want a pre/post condition added to the Initialise method.
I can see that the problem is due to the abstract implementations having no way to avoid each other (either due to interception or the rewriter).
[ContractClass(typeof(IInitialiseContract))]
public interface IInitialise
{
bool IsInitialised { get; }
void Initialise();
}
[ContractClassFor(typeof(IInitialise))]
public abstract class IInitialiseContract : IInitialise
{
public bool IsInitialised
{
get { return default(bool); }
}
public void Initialise()
{
Contract.Ensures(IsInitialised == true);
}
}
then later I end up with the following interface
[ContractClass(typeof(IEnginecontract))]
public interface IEngine : IInitialise
{
ICommandManager CommandManager { get; }
IDictionary<int, IEntity> World { get; }
}
[ContractClassFor(typeof(IEngine))]
public abstract class IEnginecontract : IEngine
{
public ICommandManager CommandManager
{
get
{
Contract.Ensures(Contract.Result<ICommandManager>() != null);
return default(ICommandManager);
}
}
public IDictionary<int, IEntity> World
{
get
{
Contract.Ensures(Contract.Result<IDictionary<int, IEntity>>() != null);
return default(IDictionary<int, IEntity>);
}
}
public bool IsInitialised
{
get { return default(bool); }
}
public void Initialise()
{
// I would like to put my pre and post conditions here but
// cannot because it is implemented in the base interfaces contract.
}
}
I get to here and i cannot figure out a nice clean way to add conditions to Initialise().
Edit2: If I had put a requires in this method i would of got an error like this
Warning 1 Contract class IEngine cannot define contract for method IInitialise.Initialise as its original definition is not in type IEngine . Define the contract on type IInitialise instead. IEngine .cs
Any ideas?
Any methods which are from an interface other than the one you're writing the contracts for should be marked abstract. The contracts for these methods will be inherited automatically, and you can't change them (or this would alter the meaning of the base interface, which doesn't make sense).
So you should have your base interface and its contracts:
[ContractClass(typeof(IInitialiseContract))]
public interface IInitialise
{
bool IsInitialised { get; }
void Initialise();
}
[ContractClassFor(typeof(IInitialise))]
public abstract class IInitialiseContract : IInitialise
{
public bool IsInitialised
{
get { return default(bool); }
}
public void Initialise()
{
Contract.Ensures(IsInitialised == true);
}
}
And your derived interface and its contracts (note abstract inherited ones):
[ContractClass(typeof(IEnginecontract))]
public interface IEngine : IInitialise
{
ICommandManager CommandManager { get; }
IDictionary<int, IEntity> World { get; }
}
[ContractClassFor(typeof(IEngine))]
public abstract class IEnginecontract : IEngine
{
public ICommandManager CommandManager
{
get
{
Contract.Ensures(Contract.Result<ICommandManager>() != null);
return default(ICommandManager);
}
}
public IDictionary<int, IEntity> World
{
get
{
Contract.Ensures(Contract.Result<IDictionary<int, IEntity>>() != null);
return default(IDictionary<int, IEntity>);
}
}
public abstract bool IsInitialised {get;}
public abstract void Initialise();
}
I don't think it's possible. I use code contracts extensively and as far as I can tell -- I remember having tried something like this myself -- your derived interface's code contract must include all conditions again, it cannot inherit them.
Related
i'm trying to build a sort of framework for some base process in an app. There is some common behavior where i have to execute some operations but these operations are different depending on some scenarios. I have done something i'm not sure if it's considered a bad practice to make something like this:
public interface IMyDto
{
string makerIdentifier { get; set; }
}
public class DtoOne:IMyDto
{
public string makerIdentifier { get; set; }
//Custom properties for ConcreteOne
}
public class DtoTwo:IMyDto
{
public string makerIdentifier { get; set; }
//Custom properties for ConcreteTwo
}
public abstract class AbstractMaker
{
public abstract void DoSomething(IMyDto myInterface);
}
public class ConcreteMakerOne:AbstractMaker
{
public override void DoSomething(IMyDto myInterface)
{
var concrete = myInterface as DtoOne;
// If concrete is not null..do stuff with DtoOne properties
}
}
public class ConcreteMakerTwo : AbstractMaker
{
public override void DoSomething(IMyDto myInterface)
{
var concrete = myInterface as DtoTwo;
// If concrete is not null..do stuff with DtoTwo properties
}
}
public class Customer
{
public void MakeSomething(IMyDto myDto)
{
var maker = GetMaker();
maker.DoSomething(myDto);
}
private AbstractMaker GetMaker()
{
//Stuff to determine if return ConcreteOne or ConcreteTwo
}
}
The code im not happy with is the:
var concrete = myInterface as DtoOne;
I would appreciate a lot if someone could give me some advide or tips about a pattern or good oop practice for this scenario.
It's not clear what all of your use cases are, but one option might be generics:
public abstract class AbstractMaker<T> where T:IMyDto
{
public abstract void DoSomething(T myInterface);
}
public class ConcreteMakerTwo : AbstractMaker<DtoTwo>
{
public override void DoSomething(DtoTwo myInterface)
{
// now you are certain that myInterface is a DtoTwo
}
}
I am not sure if I understand correctly what are you asking about, but why not just put method DoSomething in IMyDto and implement it differently in DtoOne, DtoTwo, etc.? There would be only one Maker and would always call the same method.
I have this setup, and it didn't work as I expected. It seems to me that a generic T in a base class is not the same as the generic T in its sub-class.
namespace StackOverflowQuestion
{
public class Poco1
{
public string Data { get; set; }
}
public class Poco2 : Poco1
{
public string ExtraData { get; set; }
}
public class Poco3 : Poco2
{
public string EvenMoreData { get; set; }
}
public class Base<T> where T: Poco1
{
public virtual void Method(T parameter)
{
// Do something even more general with Data...
parameter.Data = "Test";
}
}
public class FirstLevel<T> : Base<Poco2> where T:Poco2
{
public override void Method(Poco2 parameter)
{
// Do something general with ExtraData...
base.Method(parameter);
}
}
public class SecondLevel<T> : FirstLevel<Poco3> where T: Poco3
{
public override void Method(Poco2 parameter) // <-- Why not Poco3?
{
// Do something with EvenMoreData...
base.Method(parameter);
}
}
}
What I actually expected was that the Method override in type SecondLevel<T> should say Poco3 and not Poco2. Especially as I put a constraint on T to be of type Poco3.
Is it possible to achieve this in another way? It seems to me that the generic T can't be "overridden" the way I wanted. I suspect T in Base<T> is not the same as T in FirstLevel<T> and that T in FirstLevel<T> is not the same as T in SecondLevel<T>?
If SecondLevel<T> inherits from Base<T> then I get Poco3 in the Method override, but not when I inherit from FirstLevel<T>.
I can live with this issue, but then I need to cast the poco parameter type in Level-type sub-classes (from level 2 and up). In my opinion, that should be unnecessary as long as I specify the constraint. But, of course, there might be a good reason for this behavior that I don't see at the moment.
Rather than specifying the POCO type in each overridden method signature you can instead use the T type parameter.
T is already constrained to the POCO type you want so it should behave exactly as you want.
Oh, and I'd do the same with the type you're passing to the base class as well.
e.g.
public class FirstLevel<T> : Base<T> where T:Poco2
{
public override void Method(T parameter)
{
// Do something general with ExtraData...
base.Method(parameter);
}
}
public class SecondLevel<T> : FirstLevel<T> where T: Poco3
{
public override void Method(T parameter)
{
// Do something with EvenMoreData...
base.Method(parameter);
}
}
I have an interface which has a property like this:
public interface IMyInterface
{
IGenericThing MyProperty { get; set; }
}
I implement that interface in a specific class that uses a generic type, but in that class, I want to use a specific implementation of IGenericThing, like this:
public abstract class MySpecificClass<T> : IMyInterface
where T : IGenericThing
{
IGenericThing IMyInterface.MyProperty
{
get { return myProperty; }
set
{
if (value is T)
{
MyProperty = (T)value;
}
}
}
protected T myProperty;
public T MyProperty
{
get { return myProperty; }
set
{
myProperty = value;
//...other setter stuff
}
}
}
This all works, which is awesome. It lets me access MyProperty when I have a reference to an object through IMyInterface, and access more specific information about MyProperty when I know it's an instance of MySpecificClass.
What I don't really understand is what this is called or what the compiler is doing to let this happen. I tried searching for this, but since I don't know what it's called, couldn't find anything.
Can anybody please explain what is going on here so that I can understand this better?
That's called explicit interface implementation
if a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation.
It's not exactly your case but here you have a classic usage for it
interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
I have an interface here named IFish. I want to derive it with an abstract class (WalkingFishCommon) which provides an incomplete implementation, so that classes derived from WalkingFishCommon do not have to implement the CanWalk property:
interface IFish
{
bool Swim();
bool CanWalk { get; }
}
abstract class WalkingFishCommon : IFish
{
bool IFish.CanWalk { get { return true; } }
// (1) Error: must declare a body, because it is not marked
// abstract, extern, or partial
// bool IFish.Swim();
// (2) Error: the modifier 'abstract' is not valid for this item
// abstract bool IFish.Swim();
// (3): If no declaration is provided, compiler says
// "WalkingFishCommon does not implement member IFish.Swim()"
// {no declaration}
// (4) Error: the modifier 'virtual' is not valid for this item
// virtual bool IFish.Swim();
// (5) Compiles, but fails to force derived class to implement Swim()
bool IFish.Swim() { return true; }
}
I've not yet discovered how to make the compiler happy, while still achieving the goal of forcing classes derived from WalkingFishCommon to implement the Swim() method. Particularly baffling is the delta between (1) and (2), where the compiler alternates between complaining that Swim() isn't marked abstract, and in the next breath complains that it can't be marked abstract. Interesting error!
Any help?
Just declare Swim as abstract and don't try to use explicit interface declaration for it (i.e. remove IFish).
abstract class WalkingFishCommon : IFish
{
public bool CanWalk { get { return true; } }
public abstract bool Swim();
}
Typically, interfaces are implemented implicitly by defining a public member in the class for each member of the interface:
class MyFish : IFish
{
public bool CanWalk { get { return ...; } }
public bool Swim() { return ...; }
}
If you do not want to provide an implementation for one of these members, you can simply make it abstract:
abstract class FishBase : IFish
{
public virtual bool CanWalk { get { return true; } }
public abstract bool Swim();
}
If you really need to implement the interface explicitly, you can create two members: one abstract member that must be overridden by the derived class, and one member implementing the interface and forwarding the call to the first member:
abstract class FishBase : IFish
{
public virtual bool CanWalk { get { return true; } }
protected abstract bool Swim();
bool IFish.Swim() { return Swim(); }
}
If you don't really need to implement the interface explicitly, you could simply do this:
abstract class WalkingFishCommon : IFish {
public abstract bool CanWalk { get; }
public abstract bool Swim();
}
If the explicit implementation is important, you can solve the problem by introducing protected abstract methods:
abstract class WalkingFishCommon : IFish {
bool IFish.CanWalk { get { return CanWalkCore; } }
bool IFish.Swim() { return SwimCore(); }
protected abstract bool CanWalkCore { get; }
protected abstract bool SwimCore();
}
Not exactly a solution but maybe you could do something like
interface IWalkingFish
{
bool CanWalk { get; }
}
interface ISwimmingFish
{
bool Swim();
}
interface IFish : ISwimmingFish, IWalkingFish
{ }
abstract class WalkingFishCommon : IWalkingFish
{
bool IWalkingFish.CanWalk { get { return true; } }
}
Then you can use the different interfaces for the abstract and concrete classes.
Hey, I'd like to know if what I'm trying to do is even possible? Comments in code should give and idea what I'm trying to achive :)
interface ITest<T> {
T t { get; }
bool DoTest();
}
public abstract class Test<T> : ITest<T> {
public Test (T nt) {
this.t = nt;
}
public Test () {
}
public T t {
get;
private set;
}
public abstract bool DoTest ();
}
public class STest : Test<string> {
public override bool DoTest () {
return true;
}
}
public class ITest : Test<int> {
public override bool DoTest () {
return true;
}
}
public class TestTest {
// I don't want to specify type here, I'd like TestTest to be able to have
// either a ITest or a STest. But for this class it should not matter.
// I just want to use DoTest() later on. No matter what
// specialication of Test this is.
Test myTest;
}
This might be a design problem, and I'd be willing to reconsider that if it is :)
I would suggest extracting the DoTest method to a super-interface, like this:
interface ITestable
{
bool DoTest();
}
interface ITest<T> : ITestable
{
T t { get; }
}
public class TestTest
{
ITestable myTest;
}
On an unrelated note, it is not recommended for class-names to begin with 'I' and for properties to begin with lower-case characters.
Place the DoTest() method in a non-generic ITest interface. Also, I would recommend making the ITest interface have a non-generic version of t. This is a quite common approach seen with interfaces like IEnumerable and IEnumerable<T>. The advantage is the non-generic version doesn't get less-capable and can hence can be fully leveraged in places where no actual type parameter can be supplied.
interface ITest
{
object t { get; }
bool DoTest();
}
interface ITest<T> : ITest
{
T t { get; }
}
Thanks to explicit implementation the unwanted non-generic or generic version (depending on the actual situation) can be hidden:
class STest : ITest<S>
{
public string t { get; private set; }
string ITest.t { get { return t; } }
public bool DoTest { ... }
}