Suggestion - interfaces and constraints

A

Andrew Ducker

Let's say I have an interface (IValid) I want to add to all the
different Winform.Controls classes (textbox, radiobutton, etc). And I
have a bunch of methods that then use these IValid Controls. Sometimes
they access them as Controls, sometimes as IValids. Which means
casting back and forth. You end up with things like:

DoStuffWithControls(((Control)validControl).Controls);
rather than
DoStuffWithControls(validControl.Controls);

and I know which one I prefer.

Having thought about how Generics use Constraints, it occured to me
that with a simple addition of inheritance constraints you could say
that a IValid can only be implemented by a Control, and therefore it
would automatically have all the methods/properties of both IValid
_and_ Control.

No casting would be necessary and the code would be cleaner/simpler.

Any thoughts?

Andy
 
J

Jon Skeet [C# MVP]

Andrew Ducker said:
Let's say I have an interface (IValid) I want to add to all the
different Winform.Controls classes (textbox, radiobutton, etc). And I
have a bunch of methods that then use these IValid Controls. Sometimes
they access them as Controls, sometimes as IValids. Which means
casting back and forth. You end up with things like:

DoStuffWithControls(((Control)validControl).Controls);
rather than
DoStuffWithControls(validControl.Controls);

and I know which one I prefer.

Having thought about how Generics use Constraints, it occured to me
that with a simple addition of inheritance constraints you could say
that a IValid can only be implemented by a Control, and therefore it
would automatically have all the methods/properties of both IValid
_and_ Control.

No casting would be necessary and the code would be cleaner/simpler.

Any thoughts?

Do you mean like this?

using System;

interface ISomething
{
void Foo();
}

class Base
{
public void Bar()
{
}
}

class Derived : Base, ISomething
{
public void Foo()
{
}
}

class Test
{
static void Main()
{
Derived d = new Derived();

UseBoth (d);
}

static void UseBoth<T> (T instance) where T : Base, ISomething
{
instance.Foo();
instance.Bar();
}
}
 
A

Andrew Ducker

Jon said:
Do you mean like this?

static void UseBoth<T> (T instance) where T : Base, ISomething
{
instance.Foo();
instance.Bar();
}
}

Oooh, that is nice. But it requires the use of generics. What I'd
like is

class Bar
{
public void Bar
{
...
}
}

class Derived : Bar, ISomething
{
public void Foo()
{
....
}
}

interface ISomething : where Bar
{
void Foo();
}

Class Derived1

class Test
{
static void Main()
{
Derived d = new Derived();

UseBoth (d);
}


static void UseBoth(ISomething instance)
{
instance.Foo();
instance.Bar();
}
}

The "where" in the interface effectively saying that "You can't
implement this interface in anything other than a Bar." meaning that
ISomething automatically has all of the properties/methods of a Bar.

The advantage there is that I can have a private member variable of
type ISomething that I can use as a Bar without recasting.

Andy
 
A

Andrew Ducker

Actually, scratch what I said just there - I worked out a way to do it:

interface IValid
{
void ValidateMe();
}

class ValidTextBox: TextBox, IValid
{
ValidImplementation<ValidTextBox> v;

public ValidTextBox()
{
v = new ValidImplementation<ValidTextBox>(this);
}

#region IValid Members
public void ValidateMe()
{
v.ValidateMe();
}
#endregion
}


class ValidImplementation<T> : IValid where T: Control,IValid
{
T control;

public ValidImplementation(T control)
{
this.control = control;
}

#region IValid Members
public void ValidateMe()
{
foreach (Control c in control.Controls)
{
//Do Stuff
}
}
#endregion
}

Cheers for the pointer in your previous post - it cracked it for me!

Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top