C#C
C#2y ago
popcorn

Fluent Syntax - generic methods

Hi, I have a structure as follows:
public abstract class Control { }

public sealed class Image : Control {
    public Image WithUrl(string url) { Url = url; return this; }
    public Image WithZoomFactor(float zoomFactor) { ZoomFactor = zoomFactor; return this; }
}

public sealed class Label : Control {
    public Label WithText(string text) { Text = text; return this; }
}

public class StackPanel: Control {
    public void AddChild(Control control) { }
}

public class Canvas: Control {
    public void AddChild(Control control, Point point) { }
}


and I want to be able to do :
new Image()
    .WithZoomFactor(0.75f)
    .PlacedIn(canvas1).At(0, 0)
    .WithUrl("flower2.jpg");

new Image()
    .WithZoomFactor(0.75f)
    .PlacedIn(stackPanel2)
    .WithUrl("flower1.jpg");

new Label()
    .WithText("Dandelion (lat. Taraxacum officinale)")
    .PlacedIn(canvas2).At(50, 200);

// This should not compile - PlaceIn() is in canvas and is not followed by .At()..
// new Image().PlacedIn(canvas2).WithUrl("flower2.jpg");

So the rule is that the method .PlacedIn(canvas) must be either last to be called or must be followed by .At().
And .PlacedIn(stackPanel) can be anywhere and followed by any method.

The second problem I solved quite easily by:

public static T PlacedIn<T>(this T control, StackPanel stackPanel) where T : Control {
    return control;
}


But I'm not sure about the .PlacedIn(canvas). I think it should return some other type than the generic T where : Control but then the information about the type is lost and I don't know how to return the proper type (Label, Image, ...) In the .At() method afterwards.
How can I do this?
Was this page helpful?