Question on Casting to a BaseType

C

Chris

I created a control that derives from the System.Windows.Forms.Control
namespace.
I then created an interface to which this new control must adhere, so that I
could require future controls to provide certain functionality.

In my form code, I'm not going to be sure of what types of controls the form
will be using until run-time. So, I created an array of controls, all cast
as Control. This all works fine, so far.

Now, in the form code, I figured out how to determine whether or not the
control I'm currently accessing from the control array implements my
interface. I did this using a call to
currentControl.GetType().GetInterface("InterfaceName"). However, because
currentControl is reference as a System.Windows.Forms.Control, rather than
as a MyControl, I can't cast to the interface.

Does anyone know a way of casting to the interface and accessing the
properties that the interface defines? Obviously, it's going to be very
counter-productive to have to create a whole set of custom controls that
merely inherit from the various Windows forms controls, just so that I can
make sure that all of the implement my interface.

The closest MSDN help article I could find is this:
<ms-help://MS.VSCC/MS.MSDNVS/vbcon/html/vbconwhenshouldiimplementinterfacesi
nmycomponent.htm>, and indicates code like the following:

BusinessAccount business = new BusinessAccount();
IAccount account = business;
account.PostInterest();

Here's some sample code:

using System.Windows.Forms

Control[] controlArray;

..... get controls into the array, from various sources....

if (controlArray.GetType().GetInterface( "MyInterface", true ) != null )
{
MyInterface interfaceInst = controlArray;
int propertyValue = interfaceInst.Property1;
}

Unfortunately, this code throws an InvalidCastException. Using a casting
statement (i.e. "MyInterface interfaceInst = (MyInterface)
controlArray;") doesn't work, either.

Anyone have any ideas?

Thanks,

Chris
 
M

Mattias Sjögren

Now, in the form code, I figured out how to determine whether or not the
control I'm currently accessing from the control array implements my
interface. I did this using a call to
currentControl.GetType().GetInterface("InterfaceName").

It would be eaiser and faster to do

if ( currentControl is InterfaceName )

However, because
currentControl is reference as a System.Windows.Forms.Control, rather than
as a MyControl, I can't cast to the interface.

If a cast succeeds or not depends on the actual type of the object,
not the type of the reference you hold to it. So if the the interface
is supported, the cast should succeed even though you hold a Control
reference to it.

Unfortunately, this code throws an InvalidCastException. Using a casting
statement (i.e. "MyInterface interfaceInst = (MyInterface)
controlArray;") doesn't work, either.

Anyone have any ideas?


In that case the class apparently doesn't implement the interface. I'm
not sure why that might be. You haven't used "copy and paste" code
reuse, have you? In other words, the implementing class and the
consuming class are using the same definition of the interface, right?



Mattias
 
C

Chris

Thanks for responding!

I tried using the "is" statement, and it doesn't work; after reading up on
the keyword, I'm guessing that it's due to the same reason that's throwing
the InvalidCastException when I try to cast.

Regarding the casting, and the implementation of the interface, as far as I
can tell, I've implemented the same interface in both classes. I _have_
implemented two interfaces, the second of which inherits from the first.
The code is similar to the following (minus obvious references to control
assemblies, etc.):

namespace MyApp.MyInterfaces
{
public interface IMyFirstInterface
{
int MyIntValueProp { get; set; }
object[] MyObjArrayProp { get; set; }
string[] MyStrArrayProp { get; set; }
}
}

namespace MyApp.MyInterfaces
{
public interface IMySecondInterface : IMyFirstInterface
{
MySecondIntProp { get; set; }
string MyStrProp { get; set; }
}
}

using MyApp.MyInterfaces;
using System.Windows.Forms;
namespace MyApp.MyClasses
{
public class MyControlClass : System.Windows.Form.Control,
IMySecondInterface
{
public MyControlClass()
{
// some constructor code
}

// some other code
}

Do you see any problems with this implementation?

Mattias Sjögren said:
Now, in the form code, I figured out how to determine whether or not the
control I'm currently accessing from the control array implements my
interface. I did this using a call to
currentControl.GetType().GetInterface("InterfaceName").

It would be eaiser and faster to do

if ( currentControl is InterfaceName )

However, because
currentControl is reference as a System.Windows.Forms.Control, rather than
as a MyControl, I can't cast to the interface.

If a cast succeeds or not depends on the actual type of the object,
not the type of the reference you hold to it. So if the the interface
is supported, the cast should succeed even though you hold a Control
reference to it.

Unfortunately, this code throws an InvalidCastException. Using a casting
statement (i.e. "MyInterface interfaceInst = (MyInterface)
controlArray;") doesn't work, either.

Anyone have any ideas?


In that case the class apparently doesn't implement the interface. I'm
not sure why that might be. You haven't used "copy and paste" code
reuse, have you? In other words, the implementing class and the
consuming class are using the same definition of the interface, right?



Mattias
 
S

Sunny

Hi Chris,
In addition to Mattias's question:
1. are you sure that all objects in controllArray are implementing the
interfaces?
2. Here in the group somewhere I have read something interesting about
"is" keyword, i.e. if you are planning to use "is" only as preparation
to a cast, its better to use "as", so maybe you should try:

instead
Control[] controlArray;

.... get controls into the array, from various sources....

if (controlArray.GetType().GetInterface( "MyInterface", true ) != null )
{
MyInterface interfaceInst = controlArray;
int propertyValue = interfaceInst.Property1;
}


try this:

MyInterface obj = controlArray as MyInterface;
int propertyValue;
if (obj != null)
{
propertyValue = obj.Property1;
}



Sunny
 
M

Mattias Sjögren

Chris,
Do you see any problems with this implementation?

No, other than the fact that the MySecondIntProp is lacking a return
type, but I assume that's just a typo.

Is the interface defined in a separate assembly? If so, double check
that you're referencing the same version of that assembly.



Mattias
 

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