Ich habe ein Problem bei der Verwendung von Invarianten mit Code-Verträgen festgestellt. Ich möchte eine Invariante innerhalb meiner abstrakten Klasse definieren, aber sie wird einfach ignoriert. Der folgende Code zeigt meine Schnittstelle und die abstrakte Klasse.Code Contracts: Invarianten in abstrakte Klasse
[ContractClass(typeof(IPointContract))]
interface IPoint
{
int X { get; }
int Y { get; }
}
[ContractClassFor(typeof(IPoint))]
abstract class IPointContract : IPoint
{
public int X
{
get { return 0; }
}
public int Y
{
get { return 0; }
}
[ContractInvariantMethod]
private void PointInvariant()
{
Contract.Invariant(X > Y);
}
}
Danach implementiere ich diese Schnittstelle innerhalb meiner Point-Klasse und erstelle ein Objekt daraus. Dies sollte zumindest während der Laufzeit fehlschlagen.
class Point : IPoint
{
public Point(int X, int Y)
{
this._x = X;
this._y = Y;
}
private int _x;
public int X
{
get { return _x; }
}
private int _y;
public int Y
{
get { return _y; }
}
}
class Program
{
static void Main(string[] args)
{
Point p = new Point(1, 2);
}
}
Als ich die unveränderliche auf den Punkt-Klasse bewegen, es funktioniert gut. Alle anderen Vor- oder Nachbedingungen funktionieren auch gut.
Ist es nicht möglich, Invarianten innerhalb einer abstrakten Klasse zu haben, oder mache ich es falsch?
Warum benennen Sie eine abstrakte Klasse mit Interface-Semantik? Eine abstrakte Klasse ist keine Schnittstelle und sollte nicht mit I beginnen. –
Ich verwende die gleiche Semantik wie im Code-Vertragshandbuch. Siehe Kapitel 2.8 http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf – Dynamike
Ich sehe ... Es ist nicht I-FooContract, es ist IFoo-Contract. Wenn ich es wäre, würde ich es wahrscheinlich ContractForIFoo schreiben, um klar zu sein, aber vielleicht gibt es hier eine Konvention ... –