Implement interface for that class, not dervived classes

G

g18c

Hi, im trying to do something and just been caught off guard. I want
to implement an interface but only for certain class, but of course
when i derive from this base class the derived class also inherits the
interface.

public class Base : IGetType
{
protected byte m_type;

object IGetType.TypeIdentifier
{
get { return m_type; }
}
}

public class Base2 : Base
{
}

void TestingFunc()
{
object obj = new Base2();
if (obj is IGetType)
{
// Base2 implements IGetType
}
}

I am checking objects because i am doing a recursive check against
arbitary types to see if they implement the interface. Now i want Base
to implement the interface, but not inherit it to Base2. Furthermore i
do need Base2 to inherit from Base. I know that is the definition of
inheritance, so maybe someone would be kind enough to think about how
else i could do this?

Many thanks,

Chris
 
L

Larry Lard

Hi, im trying to do something and just been caught off guard. I want
to implement an interface but only for certain class, but of course
when i derive from this base class the derived class also inherits the
interface.

public class Base : IGetType
{
protected byte m_type;

object IGetType.TypeIdentifier
{
get { return m_type; }
}
}

public class Base2 : Base
{
}

void TestingFunc()
{
object obj = new Base2();
if (obj is IGetType)
{
// Base2 implements IGetType
}
}

I am checking objects because i am doing a recursive check against
arbitary types to see if they implement the interface. Now i want Base
to implement the interface, but not inherit it to Base2. Furthermore i
do need Base2 to inherit from Base. I know that is the definition of
inheritance, so maybe someone would be kind enough to think about how
else i could do this?

Without knowing what these classes actually are and what they represent,
it's hard to offer much advice. By the definition of inheritance, all
instances of Base2 instances *are* instances of Base also, thus
implement IGetType. I suppose you _could_ override the
IGetType-implementing functions in Base2 and throw
NotSupportedExceptions if they are invoked, but this would be ugly in
the extreme, happen at runtime rather than compile time, and I'm not
sure it would work.

You need to work out semantically what you actually want to be happening
here.
 
S

Samuel R. Neff

Use three classes:

public class Base {
.. base class stuff...
}

public class Base2 : Base {
... child class stuff ...
}

public class BaseWithGetType : Base, IGetType {
... IGetType implementation ...
}

And then in your app use BaseWithGetType instead of Base.

If the purpose of this is specifically for reflection and identifying
classes then perhaps you'd be better off using Attributes than
Interface implementation. Something like:

[TypeIdentifier(2)]
public class Base { }

public class Base2 : Base { }

Then Base will have the attribute but Base2 will not (well, it will or
won't depending the parameters passed to GetCustomAttributes).

HTH,

Sam
 
J

Jon Skeet [C# MVP]

Hi, im trying to do something and just been caught off guard. I want
to implement an interface but only for certain class, but of course
when i derive from this base class the derived class also inherits the
interface.

And so it should. Anything you can do with a base class, you must be
able to do with a derived class. Search for "Liskov Substitution
Principle" for more details.
I am checking objects because i am doing a recursive check against
arbitary types to see if they implement the interface. Now i want Base
to implement the interface, but not inherit it to Base2. Furthermore i
do need Base2 to inherit from Base. I know that is the definition of
inheritance, so maybe someone would be kind enough to think about how
else i could do this?

Check whether the object implements the interface, and then if it does,
exclude it if its base type implements the interface too?

Sounds a bit ugly though - have you considered using non-inherited
attributes to mark the types that you want to consider?
 
G

g18c

Sounds a bit ugly though - have you considered using non-inherited
attributes to mark the types that you want to consider?

Thanks for the replies, i have done some thinking and how about
keeping a list of registered types? If the type is registered i would
then go on to call the objects interface (which of course must be
implemented by the registered type).

public interface IGetType
{
object TypeIdentifier {get;}
}

public class Base : IGetType
{
protected byte m_type;

public object TypeIdentifier
{
get { return m_type; }
}
}

public class Base2 : Base
{
public Base2()
{
base.m_type = 0x01;
}
}

public class Base3 : Base, IGetType
{
UInt32 m_Subtype = 0x100;

public Base3()
{
base.m_type = 0x02;
}

object IGetType.TypeIdentifier
{
get { return m_Subtype; }
}
}

void test()
{
List<Type> ht = new List<Type>();
ht.Add(typeof(Base));
ht.Add(typeof(Base3));

object obj2 = new Base();
bool isRegistered = ht.Contains(obj2.GetType()); //
true
if (isRegistered && (obj2 is IGetType))
{
// prints: Type: System.Byte, Value: 0
object next = ((IGetType)obj2).TypeIdentifier;
Console.WriteLine("Type: " + next.GetType() + ",
Value: " + next);
}

obj2 = new Base2();
isRegistered = ht.Contains(obj2.GetType()); // false
if (isRegistered && (obj2 is IGetType))
{
object next = ((IGetType)obj2).TypeIdentifier;
Console.WriteLine("Type: " + next.GetType() + ",
Value: " + next);
}

obj2 = new Base3();
isRegistered = ht.Contains(obj2.GetType()); // false
if (isRegistered && (obj2 is IGetType))
{
object next = ((IGetType)obj2).TypeIdentifier;
// prints: Type: System.UInt32, Value: 256
Console.WriteLine("Type: " + next.GetType() + ",
Value: " + next);
}
}

This does work and do excatly what i want, but maybe there are nicer
ways of doing the same?

Thanks in advance,

Chris
 
G

g18c

This does work and do excatly what i want, but maybe there are nicer
ways of doing the same?
Actualy answering this question i think you are correct in that
attributes will be the way to go and make for much nicer code.

Cheers for the ideas,

Chris
 

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