views:

261

answers:

1

I wish to declare a variable in such a way as it can be assigned only values which derive from Control and also implement the ISomething interface.

I intend to add the ISomething interface to derivatives of controls.

I would like to derive SpecialTextBox and SpecialDatePicker From TextBox and DatePicker and implement the ISomething interface on each.

I would like to be able to assign each of these controls to a variable whose type is "Control which also implements ISomething" so that from there they could either have their ISomething methods invoked or could be added to a control collection on a form.

So.... How do I declare a variable of Type "Control which also implements ISomething"?

Ideally the answer to be in VB.Net but I would be interested in a C# method also.

+10  A: 

One way to do this is with generics - i.e. a generic method:

void Foo<T>(T control) where T : Control, ISomething
{
    // use "control"
    // (you have access to all the Control and ISomething members)
}

Now you can call Foo only with other variables that are a Control that implements ISomething - you don't need to specify the generic, though:

Foo(someName);

is all you need. If you've given it something that isn't both a Control and ISomething, the compiler will tell you.


Update: I don't "do" VB, but reflector tells me that the above translates as:

Private Sub Foo(Of T As { Control, ISomething })(ByVal control As T)

End Sub
Marc Gravell
It's going to take a moment for me to comprehend this but it's what I'm after
Rory Becker
erm cannot delete previous comment to restate it... I meant "...but (I suspect) it's ..."
Rory Becker
So if I understand this correctly... Within the scope of this method...the Type T will meet my requirements.... Well Damn that's good enough... Thanks very much... Great stuff. I can see why your rep is so high :)
Rory Becker
That is exactly what the generic constraints mean, yes. Within Foo, you are guaranteed that the type T (supplied by the caller) meets those conditions.
Marc Gravell
I don't suppose you can inherit from a generic constraint? :D
Rory Becker
Just tried this out...Public Class ControlFactory Public Function CreateControl(Of T As {Control, ISControl})() As T Return New STextBox 'This not allowed :( End FunctionEnd ClassPublic Class STextBox Inherits Control Implements ISControlEnd Class
Rory Becker
Do you want to create objects inside the method? In which case, add `, new()` to the constraints (`, New` in VB) and you can use `new T()` in the method (with similar VB). So if you call it with a <STextBox> generic-type-argument, you will get a new STextBox
Marc Gravell