Tod
Tod

Reputation: 2524

c# base class method returns derived class

So I have an app calling a LOAD of WebServices, all of which have a response class, each response class is derived from ResponseBase

public abstract record ResponseBase<T>
{
    public HashSet<string> ErrorMessages { get; set; }

    public bool Success { get; set; }

    public virtual string Message => Success ? "Success" : string.Join(", ", ErrorMessages);

    public IEnumerable<T> Results { get; set; }
    public T Result { get; set; }
}

Now I currently create new responses like this:

var results = SomeService.GetSomeResults();
return new SomeDerivedResponse() { Success = true; Results = results }

For brevity, clarity, general code cleanliness what I'd LIKE to do is some more like:

var results = SomeService.GetSomeResults();
return new SomeDerivedResponse().WithSuccess(results);

WithSuccess() will just assign Success = true and Results = results accordingly

Without having to put the same WithSuccess() method in each of the derived response classes (Theres hundreds of them). I almost got there with a generic WithSuccess() method in the base class but it returns the base class, not the derived class, meaning I have this double-take:

return new SomeDerivedResponse().WithSuccess<SomeDerivedResponse>(results);

Any way I can either tell the compiler what the inference is, or is there a better way to do this?

Upvotes: 1

Views: 190

Answers (1)

Guru Stron
Guru Stron

Reputation: 141565

Using generic extension methods like this should work:

public static class Ext
{
    public static T WithSuccess<T, R>(this T t, IEnumerable<R> r) where T : ResponseBase<R>
    {
        // your logic here
        return t;
    }

    public static T WithSuccess<T, R>(this T t, R r) where T : ResponseBase<R>
    {
         // your logic here
        return t;
    }
}

And usage:

public record SomeDerivedResponse : ResponseBase<int>{}
public record SomeDerivedResponse1<T> : ResponseBase<T>{}

new SomeDerivedResponse().WithSuccess(new []{1});
new SomeDerivedResponse1<int>().WithSuccess(1);

Upvotes: 3

Related Questions