Abstracts: can I do better than this?
-
I know I'm missing something simple. I have a base class, Device, and a bunch of derived classes Dev1, Dev2... Depending on the type of device active at the moment, I have an abstract method for each derived type. Deciding which to use leads me to:
if (SelectedDevice.GetType() == typeof(Dev1))
{
SetDevice((Dev1)SelectedDevice);
}
else if (SelectedDevice.GetType() == typeof(Dev2))
{
SetDevice((Dev2)SelectedDevice);
}
else if ...It works, but it just feels ugly. Molly
You could establish an enum and then have an appropriate property in each class. Setting/getting a property probably has less impact on performance than casting.
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
I know I'm missing something simple. I have a base class, Device, and a bunch of derived classes Dev1, Dev2... Depending on the type of device active at the moment, I have an abstract method for each derived type. Deciding which to use leads me to:
if (SelectedDevice.GetType() == typeof(Dev1))
{
SetDevice((Dev1)SelectedDevice);
}
else if (SelectedDevice.GetType() == typeof(Dev2))
{
SetDevice((Dev2)SelectedDevice);
}
else if ...It works, but it just feels ugly. Molly
I've had this problem in the past. What I decided on was to have an enum and pass the type of the device to the base classes constructor. Something like...
public enum DeviceType
{
TypeA,
TypeB
}public abstract class DeviceBase
{
private DeviceType deviceType;internal DeviceBase(DeviceType deviceType) { this.deviceType = deviceType; } public DeviceType DeviceType { get { return deviceType; } }
}
public class DeviceTypeA : DeviceBase
{
public DeviceTypeA()
: base(DeviceType.TypeA)
{ }
}public class DeviceTypeB : DeviceBase
{
public DeviceTypeB()
: base(DeviceType.TypeB)
{ }
}Dave
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Why are you using VB6? Do you hate yourself? (Christian Graus) -
rather than comparing types explicitly, you could use the
is
keyword. and what is wrong with a simpleSetDevice(SelectedDevice);
? or perhapsSelectedDevice.Set()
? :)Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
Merry Christmas and a Happy New Year to all.
My apologies for using the term 'abstract' a little too loosely. The SetDevice methods control display within a form, and are not part of the Device class. I started with
SetDevice(SelectedDevice);
but the compiler kicks that back because it can't be resolved at compile time. Molly -
I know I'm missing something simple. I have a base class, Device, and a bunch of derived classes Dev1, Dev2... Depending on the type of device active at the moment, I have an abstract method for each derived type. Deciding which to use leads me to:
if (SelectedDevice.GetType() == typeof(Dev1))
{
SetDevice((Dev1)SelectedDevice);
}
else if (SelectedDevice.GetType() == typeof(Dev2))
{
SetDevice((Dev2)SelectedDevice);
}
else if ...It works, but it just feels ugly. Molly
Why can't you do something like: SelectedDevice.Set(this) Which Set being virtual (abstract), so the right one is called without the IF and also, if newer classes appear, you don't need to change the "Deciding" code.
-
I know I'm missing something simple. I have a base class, Device, and a bunch of derived classes Dev1, Dev2... Depending on the type of device active at the moment, I have an abstract method for each derived type. Deciding which to use leads me to:
if (SelectedDevice.GetType() == typeof(Dev1))
{
SetDevice((Dev1)SelectedDevice);
}
else if (SelectedDevice.GetType() == typeof(Dev2))
{
SetDevice((Dev2)SelectedDevice);
}
else if ...It works, but it just feels ugly. Molly
-
I know I'm missing something simple. I have a base class, Device, and a bunch of derived classes Dev1, Dev2... Depending on the type of device active at the moment, I have an abstract method for each derived type. Deciding which to use leads me to:
if (SelectedDevice.GetType() == typeof(Dev1))
{
SetDevice((Dev1)SelectedDevice);
}
else if (SelectedDevice.GetType() == typeof(Dev2))
{
SetDevice((Dev2)SelectedDevice);
}
else if ...It works, but it just feels ugly. Molly
Is the casting required at all? Even if SetDevice is overloaded for each type there shouldn't be a problem should there? And if not, then you still don't need to cast to each type. Edit: I just tried it and I see the problem. More information about SetDevice would be helpful. And, as Luc said, use
is
rather than comparing types. Edit: Or perhaps SetDevice should handle determining which type of device it was passed:private static void
SetDev
(
DevBase Dev
)
{
System.Console.WriteLine ( "DevBase" ) ;if ( Dev is Dev1 ) SetDev ( (Dev1) Dev ) ; else if ( Dev is Dev2 ) SetDev ( (Dev2) Dev ) ; return ;
}
modified on Wednesday, December 30, 2009 2:01 PM
-
Is the casting required at all? Even if SetDevice is overloaded for each type there shouldn't be a problem should there? And if not, then you still don't need to cast to each type. Edit: I just tried it and I see the problem. More information about SetDevice would be helpful. And, as Luc said, use
is
rather than comparing types. Edit: Or perhaps SetDevice should handle determining which type of device it was passed:private static void
SetDev
(
DevBase Dev
)
{
System.Console.WriteLine ( "DevBase" ) ;if ( Dev is Dev1 ) SetDev ( (Dev1) Dev ) ; else if ( Dev is Dev2 ) SetDev ( (Dev2) Dev ) ; return ;
}
modified on Wednesday, December 30, 2009 2:01 PM
I have a form with device information for for each type of device. Most of the information is similar, so I'm sharing a single form, using
SetDevice()
to setup fields and controls specific to each derived device type. (right now, all SetDevice methods are inside the form, not the Device classes).SelectedDevice
is instantiated as aDevice
, then cast to whichever derived class is appropriate. The cast is necessary because at compile-time,SelectedDevice
is just aDevice
, but at run-time will have a specific derived type. -
I have a form with device information for for each type of device. Most of the information is similar, so I'm sharing a single form, using
SetDevice()
to setup fields and controls specific to each derived device type. (right now, all SetDevice methods are inside the form, not the Device classes).SelectedDevice
is instantiated as aDevice
, then cast to whichever derived class is appropriate. The cast is necessary because at compile-time,SelectedDevice
is just aDevice
, but at run-time will have a specific derived type.I wonder whether or not
dynamic
s in C# 4 will do it. -
Is the casting required at all? Even if SetDevice is overloaded for each type there shouldn't be a problem should there? And if not, then you still don't need to cast to each type. Edit: I just tried it and I see the problem. More information about SetDevice would be helpful. And, as Luc said, use
is
rather than comparing types. Edit: Or perhaps SetDevice should handle determining which type of device it was passed:private static void
SetDev
(
DevBase Dev
)
{
System.Console.WriteLine ( "DevBase" ) ;if ( Dev is Dev1 ) SetDev ( (Dev1) Dev ) ; else if ( Dev is Dev2 ) SetDev ( (Dev2) Dev ) ; return ;
}
modified on Wednesday, December 30, 2009 2:01 PM
PIEBALDconsult wrote:
Or perhaps SetDevice should handle determining which type of device it was passed.
Wouldn't that mean creating a big
SetDevice
to handle all types, and just move the same code intoSetDevice
? Even if the code is a little less ugly thanks tois
. Molly -
PIEBALDconsult wrote:
Or perhaps SetDevice should handle determining which type of device it was passed.
Wouldn't that mean creating a big
SetDevice
to handle all types, and just move the same code intoSetDevice
? Even if the code is a little less ugly thanks tois
. MollyAfaik, the 'is' keyword is not fully equal to x.GetType() == typeof(y) . Let's say I have: class A class B:A (B inheriting from A) Then following (pseudo-)code:
b = new B();
b is Areturns true and
b = new B();
b.GetType() == typeof(A)returns false. The latter option checks for an exact type match.
-
Afaik, the 'is' keyword is not fully equal to x.GetType() == typeof(y) . Let's say I have: class A class B:A (B inheriting from A) Then following (pseudo-)code:
b = new B();
b is Areturns true and
b = new B();
b.GetType() == typeof(A)returns false. The latter option checks for an exact type match.
Paul89 wrote:
b = new B();
b.GetType() == typeof(A);The above test the immediate types
A.GetType() != B.GetType() && B.GetType() != A.GetType()
for a better understanding try this:b = new B();
a = new A();typeof(A).ToString();
typeof(B).toString();a.GetType().toString();
b.GetType().toString();However this works like the is keyword:
B.IsSubclassOf(A)
returns true -or-A.IsAssignableFrom(B)
returns true On the is key word: 'An is expression evaluates to true if the provided expression is non-null, and the provided object can be cast to the provided type without causing an exception to be thrown.'modified on Wednesday, December 30, 2009 2:42 PM
-
Afaik, the 'is' keyword is not fully equal to x.GetType() == typeof(y) . Let's say I have: class A class B:A (B inheriting from A) Then following (pseudo-)code:
b = new B();
b is Areturns true and
b = new B();
b.GetType() == typeof(A)returns false. The latter option checks for an exact type match.
Thanks! I think
is
works for the code I've got today, but you probably saved me from myself on some future project. Molly -
I know I'm missing something simple. I have a base class, Device, and a bunch of derived classes Dev1, Dev2... Depending on the type of device active at the moment, I have an abstract method for each derived type. Deciding which to use leads me to:
if (SelectedDevice.GetType() == typeof(Dev1))
{
SetDevice((Dev1)SelectedDevice);
}
else if (SelectedDevice.GetType() == typeof(Dev2))
{
SetDevice((Dev2)SelectedDevice);
}
else if ...It works, but it just feels ugly. Molly
-
Thanks! I think
is
works for the code I've got today, but you probably saved me from myself on some future project. MollyOr maybe not! :laugh:
-
Or maybe not! :laugh:
Who goes 400 pages deep (as of today) into a forum just to rub it in? :sigh:
-
Who goes 400 pages deep (as of today) into a forum just to rub it in? :sigh:
That'd be me. :-D But I took a shortcut -- I saw on your profile that you had only posted a few questions, I checked those few. I didn't actually know I'd find this.