Click here to Skip to main content
15,904,415 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
...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
C#
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...
C#
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:
C#
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.
Posted
Updated 9-Jul-12 14:37pm
v2
Comments
Sergey Alexandrovich Kryukov 9-Jul-12 20:37pm    
I'm trying to understand the problem...

First of all, you treat the Data Contract in a very specialized way. What "cookbook"? How about trashing this cookbook to start just thinking with your own head. Yes, an interface, an abstract class, a backing class could be used, but why do you thing this is a must? It should be used only if you have enough justification of all of it, which depends on semantic. You should start with explaining of your goals. Ultimate goals. As to the Data Contract, it does not require anything but writing appropriate attributes on types and members you need to include in the contract. And you don't show these attribute, show [some text which would not compile] in the square brackets. It does not help to understand what you really want.

Also, please define CalledBackMethodType. Again, to make your question more understandable. Where the callback is invoked?

With abstract classes and interfaces: you really need an abstract or pseudo-abstract class if you want to have polymorphic members. You need to explain what is polymorphic and -- important! -- why (because maybe you don't really need it, and your thinking is just affected by your "cookbook").

Using Data Contract is really easy. This is the main thing you should understand. To me, your problem with delegate signature and interface signature looks artificial. First of all, it would be good to understand what makes you mixing interface-based and delegate-based approach. If I don't understand your idea, please explain.
--SA
[no name] 9-Jul-12 20:40pm    
We're hoping that data contracts can be applied to the target called back method that is to be implemented later (not by us).

The idea is that if you were to implement your target method, you will be constrained to implement it as the interface describes it and you will benefit from the already written data contracts.
Sergey Alexandrovich Kryukov 9-Jul-12 20:44pm    
It does not explain anything. This is not something you should hope for, this is something you should properly design and fully prototype the development by the users. Is it a kind of plug-in architecture? And how the plug-in interfaces are couples with Data Contracts? Why using Data Contracts with plug-ins at all?
--SA
[no name] 9-Jul-12 20:49pm    
Also, by "cook book" I mean this page:

http://msdn.microsoft.com/en-us/library/dd264808.aspx
Sergey Alexandrovich Kryukov 9-Jul-12 20:57pm    
Thank you for answering this question...
Well, this is about Code Contracts, not Data Contracts as you explained, which is a very different thing. So, first try to explain what exactly you need and why, starting from the ultimate goals of all this activity.
--SA

1 solution

Just to clarify it for me...

The first response mentioned "delegate" which is a specific syntax element in C# (not just 4.0 either.) It allows one to declare a method signature.

And from the OP it seems like the question was how to pass a method signature.

So why is "delegate" not the answer?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900