views:

101

answers:

3

I want this method to be implemented however the implementer wishes in his/her subclass. This method resides in an Interface:

object GetResponseData(object response);

I put in object, because I figured if I do this, then they can specify whatever they want as the incoming response type and decide what they want this method to return. I know I should be doing this I think with Generics though.

The problem I wind up with is some implementations of this interface may not be using an HttpRequest or HttpResponse so it may be passing in an HttpResponse or something totally different to that GetResponseData method such as a WebClient object somehow...so since I don't know how it's going to be implemented, I want this to be generic somehow.

The GetResponseData is the logic to extract out the data from the response stream, deserialize it and then return the data however we want (object) to the caller.

UPDATED:

Here is my Interface as it is currently (Before your suggestions):

public interface IAPIResponse
{

    bool HasResponseErrors { get; }

    IAPIError[] APIErrors { get; }

    string ResponseStatusCode { get; }

    object GetResponseData(HttpWebResponse response);

}
+4  A: 

If you don't want to constrain the interface itself:

TReturn GetResponseData<TReturn, TResponse>(TResponse response);

Or if you do want to constrain this to an interface and implement a number of classes that handle different returns and responses:

public interface IGetReponse<TReturn, TResponse>
{
   TReturn GetResponseData(TResponse reponse);
}

However, it's worth noting that if you use the first example you'll end up with the same method duplicated across each class that interfaces from it. Perhaps an abstract implemenation would be a better way of achieving this?

public abstract class GetReponse
{
   public abstract TReturn GetResponseData<TReturn, TResponse>(TResponse response);
}
GenericTypeTea
What I dislike about this approach is that it implies (in my mind) that the GetResponseData should be able to handle most types of TReturn and TResponse. However, it's likely that a particular implementation of an interface only supports a particular TReturn and TResponse. I think the Object method is actually clearer in this case and also easier for the caller (they only have to cast the result rather than specifying both generic arguments.) I would have the concrete implementation use an explicit interface implementation and provide a concrete overload with strongly typed parameters.
Dan Bryant
@Dan - I've tried to cover all bases. Not entirely sure what the OP wants exactly, so I'm in total agreeemnt.
GenericTypeTea
well, I want to make sure any API wrappers built agrees to the contract in that there must be that method implemented in whatever subclass of that project. That is why I went with an Interface and also I do not know what type of objects might be sent in or returned (it can vary depending on what type of .NET or 3rd party object you want to use to send and receive a request/response)
CoffeeAddict
Yea, not really sure yet when to use or what an explicit interface is
CoffeeAddict
+3  A: 

I think you are asking for one of the two options below, but it's a little unclear.

Generic interface:

public interface IInterface<TResult, TInput>
{
    TResult GetResponseData(TInput response);
}

// usage
public class ImplementerOfIInterface : IInterface<string, int>
{
    // ...
    string GetResponseData( int response ) {/*  code */}
    // ... 
}

Generic method:

public interface IInterface
{
    TResult GetResponseData<TResult, TInput>(TInput response);
}
BioBuckyBall
You don't need to make the method generic if the class is. One or the other.
Jimmy Hoffa
@Jimmy Hoffa - oops, no coffee yet, thanks
BioBuckyBall
Adding TResult, TInput to the GetResponseData function is unnecessary.
gbogumil
but is your generic method above a non-abstract class as it's now implemented with TResult GetResponseData<TResult, TInput>(TInput response); which Interfaces should not have an implementation?
CoffeeAddict
Jimmy, did not know that. But what about for readability and intent. Making the method generic explains exactly what it's expecting.
CoffeeAddict
see the updated thread...added my interface
CoffeeAddict
If you create a Generic Interface, then do I assume that any class that implements this interface must pass into it a TResult and a TInput? I guess I'm asking does that interface tie the subclass's methods tightly to that interface in terms of members of that interface use that TResult, TInput?
CoffeeAddict
@CoffeeAddict I don't quite follow your question, but I will update answer with a usage of the generic interface.
BioBuckyBall
Yea...just really wondering how a generic interface works. If a subclass implements a generic interface then that subclass is required to specify the Interface types denoted <> at the top of that Interface right? But what if your subclass did not want to use one of the generic methods (yes break the contract) ..you wouldn't be able to right? because that interface requires you to pass in a type to fullfill the generic types specified at the top of that interface. So I'm saying that generic interfaces tightly bind your subclasses to those generic types specified at the top.
CoffeeAddict
@CoffeeAddict Yeah, it binds you to the interface (including the type arguments). Just the nature of the beast :) You may end up nesting the 'genericness' by introducing a type parameter on your ImplementerOfInterface that gets passed down to IInterface...etc
BioBuckyBall
A: 
STW
see the updated thread...added my interface. Return type will not match the incoming type for the GetResponseData which is why I originally used object as the type
CoffeeAddict
Rewritten.... I really think you should consider making the interface generic (making the implementor declare a specific response-type to handle), or remove the generic. In this scenario it doesn't add much value.
STW
but I don't know what types may be sent into GetResponseData, it's not always going to be an HttpWebResponse
CoffeeAddict
@CoffeeAddict if the lowest commmon denominator is `object`, then `object` is a sensible parameter. If the interface is made generic (with only `GetResponseData()` using the generic parameter) then it would make more sense--but a non-generic interface with a single non-constrained generic method provides barely any benefit.
STW
In the case of going the route of using the WebClient.DownloadString() it's not going to give me back an HttpWebResponse. It actually consumes it and deserializes it for me into a string. So that's why I say you could get an HttpWebResponse or not depending on what method you're using to send and receive resources in your core wrapper
CoffeeAddict
@CoffeeAddict -- understood. Will a given implementation of this interface need to handle multiple response-types, or will it be 1x implementation per type? If it's the former then I'd suggest ditching generics and just going with objects, if it's the later then make your interface generic rather than your method.
STW
no, just one request type... For instance if I'm using a WSDL from a 3rd party API, I wouldn't even have an HttpRequest type of call, .NET does it for you when you call whatever method that does the sending in that WSDL...so I guess in that case you wouldn't have a "response" coming back in terms of a parameter to send in to grab the data....so that sort of throws a wrench in my whole goal of ensuring that any Request classes implement a GetResponseData method so I always have some way of accessing the returned data.
CoffeeAddict
I'm actually not thinking of just taking it out and using a property like string ResponseData into my IResponse.cs and that way I can create my own method...maybe this doesn't fit in an Interface because there is just not enough commonality.
CoffeeAddict