...asking for some "hand holding" regarding interfaces, abstract classes and the implementation of callbacks...
We're hoping to leverage as much of Microsoft's .Net 4 when re-implementing in C# an existing API. ...maybe even reach the point of being able to mechanically generate the unit tests for the API...
Because of that, we must code not just interfaces and classes but abstract classes, as well; abstracts are where the data contracts go (they can't go in the interface and, of course, we don't want them in the class, itself).
The difficulty is occurring in the specification of callbacks. Given some method that wants a called back method's reference
void ControlMethod(CalledBackMethodType theMethod)
{
save theMethod somewhere so that UsefulMethod (or whomever) can be invoked later;
}
void UsefulMethod(int someArgParm) { ... }
...
ControlMethod(UsefulMethod);
The cook book approach to implementing data contracts involves the creation of:
a namespace, call it,
NAPI
...
an interface:
IAPI
...
an abstract class:
AAPI
...
and the backing class:
CAPI
...
namespace NAPI
{
[contract stuff referencing the abstract class AAPI]
interface IAPI
{
void UsefulMethod(int someArgParm);
void ControlMethod(CalledBackMethodType theMethod);
}
[contract stuff referencing the interface IAPI]
abstract class AAPI : IAPI
{
void UsefulMethod(int someArgParm) { Contract.Requires(stuff); }
void ControlMethod(CalledBackMethodType theMethod) { Contract.Requires(stuff); }
}
class CAPI : AAPI
{
No UsefulMethod, here, because that's somebody else's job.
void ControlMethod(CalledBackMethod theMethod)
{
Code, knowing that theMethod parameter has been validated
}
}
}
...and that was a disaster. After much futzing around, not all of it coherent, this seems to be accepted:
namespace NAPI
{
[contract stuff referencing the abstract class ACB]
interface ICB {
void UsefulMethod(int someArgParm);
}
[contract stuff referencing the interface ICB]
abstract class ACB : ICB
{
void UsefulMethod(int someArgParm) { Contract.Requires(stuff); }
}
[contract stuff referencing the abstract class AAPI]
interface IAPI
{
void ControlMethod(ICB theMethod);
}
[contract stuff referencing the interface IAPI]
abstract class AAPI : IAPI, ICB
{
void ControlMethod(ICB theMethod) { Contract.Requires(stuff); }
}
class CAPI : AAPI
{
void ControlMethod(ICB theMethod) { ... }
}
}
...and that is accepted, but the signature is of interface
ICB
rather than any method declared within that interface. What's up with that?
If anybody would be so kind as to straighten this out for me, I'd really appreciate it. My eyeballs are spinning around painfully.