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;
}
}
}
}

Base Class Prop not hidden to Reflection by Steve

Steve
Fri Sep 12 01:41:14 CDT 2003

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

Re: Base Class Prop not hidden to Reflection by Mattias

Mattias
Fri Sep 12 02:20:23 CDT 2003

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

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.

Re: Base Class Prop not hidden to Reflection by Steve

Steve
Fri Sep 12 09:27:42 CDT 2003

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

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

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

>Well, it's not hidden from Reflection.

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

Thanks again for your help.

Steve


>-----Original Message-----
>Steve,
>
>>The unexpected behavior occurs when I try=20
>>to set gather the PropertyInfo for the derived class=20
>>property via Reflection. I get an=20
AmbiguousMatchException=20
>>as both the base class and derived class property=20
>>implementations are found.
>
>Use the Type.GetProperty(string,BindingFlags) overload=20
and include
>BindingFlags.DeclaredOnly to ignore inherited properties.
>
>
>>Perhaps I don't fully=20
>>understand the "new" modifier - I expected the base=20
class=20
>>member to be hidden completely when working with the=20
>>derived class.
>
>Well, it's not hidden from Reflection.
>
>
>
>Mattias
>
>--=20
>Mattias Sj=F6gren [MVP] mattias @ mvps.org
>http://www.msjogren.net/dotnet/
>Please reply only to the newsgroup.
>.
>