Base Class Prop not hidden to Reflection

  • Thread starter Thread starter Steve
  • Start date Start date
S

Steve

Hello,

I'm encountering an unexpected behavior when using
the "new" modifier in a derived class to hide an inherited
base class property. I use "new" intentionally so I can
change the Type of the property in the derived class, and
I can use the derived class as expected through standard
instantiation. The unexpected behavior occurs when I try
to set gather the PropertyInfo for the derived class
property via Reflection. I get an AmbiguousMatchException
as both the base class and derived class property
implementations are found. Perhaps I don't fully
understand the "new" modifier - I expected the base class
member to be hidden completely when working with the
derived class. I have included a code sample that
illustrates the behavior. If anyone could explain this, I
would be very interested in understanding. Thanks.

using System;
using System.Reflection;

namespace TestHide
{
class foo
{

[STAThread]
static void Main(string[] args)
{
Derived d = new Derived( "test" );

Console.WriteLine( "PropType:\t" +
d.Problem.GetType().ToString() );

try
{
PropertyInfo p = d.GetType().GetProperty
( "Problem" );
}
catch(AmbiguousMatchException e)
{
Console.WriteLine( "Error:\t\t" + e.Message );

PropertyInfo[] p = d.GetType().GetProperties();
for( int n = 0; n < p.Length; n++ )
{
Console.WriteLine( "Name: " + p[n].Name
+ "\tType: " + p[n].PropertyType
+ "\tDecl: " + p[n].DeclaringType );
}
}
catch(Exception e)
{
Console.WriteLine( e.Message );
}
}

}


public class Base
{
protected int _works = 0;
protected object _problem = null;

public Base(){}

public virtual int Works
{
get
{
return _works;
}
set
{
_works = value;
}
}

public virtual object Problem
{
get
{
return _problem;
}
set
{
_problem = value;
}
}
}

public class Derived : Base
{

public Derived(){}

public Derived(string problem)
{
this.Problem = problem;
}

public override int Works
{
get
{
return base.Works - 1;
}
set
{
base.Works = value + 2;
}
}

public new string Problem
{
get
{
return (string)base.Problem;
}
set
{
base.Problem = (string)value;
}
}
}
}
 
Sorry, forgot the output from the code listing.

PropType: System.String
Error: Ambiguous match found.
Name:Works Type:System.Int32 Decl:TestHide.Derived
Name:Problem Type:System.String Decl:TestHide.Derived
Name:Problem Type:System.Object Decl:TestHide.Base
 
Steve,
The unexpected behavior occurs when I try
to set gather the PropertyInfo for the derived class
property via Reflection. I get an AmbiguousMatchException
as both the base class and derived class property
implementations are found.

Use the Type.GetProperty(string,BindingFlags) overload and include
BindingFlags.DeclaredOnly to ignore inherited properties.

Perhaps I don't fully
understand the "new" modifier - I expected the base class
member to be hidden completely when working with the
derived class.

Well, it's not hidden from Reflection.



Mattias
 
Use the Type.GetProperty(string,BindingFlags)
overload and include BindingFlags.DeclaredOnly
to ignore inherited properties.

Thanks for the suggestion about the BindingFlags
Mattias. I tried it out, along with a few other
BindingFlags options, and it doesn't seem to work. I
think the problem is that the property in question is
actually declared at the base class, and is still
considered to be an inherited member to the derived
class, even though the derived class hides the base
member.

I know I can get around the error by either not
inheriting the member or by specifing the return-type in
the GetProperty call, but then I either lose some type-
generic parameter convenience (saves me some typecasting)
or a layer of abstraction (since I would have to know the
return type in advance).
Well, it's not hidden from Reflection.

What I'm really trying to understand is when the member
is hidden and when it's not. That is, why does
Reflection see it, but perhaps not other implementations?

Thanks again for your help.

Steve
 
Back
Top