473,326 Members | 2,110 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Reflection GetProperty Problem

Hi,

I'm going to start this off with some code as it'll make it easier to
explain afterwards...

using System;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//throws an AmbiguousMatchException
System.Reflection.PropertyInfo oPi =
typeof(ChildClass).GetProperty("Target");
}
}

//Parent Class
class ParentClass
{
public virtual object Target
{
get{return new object();}
}
}

//Child class which inherits from Parent class and hides inherited member
Target with the new keyword, and also changes the return type
class ChildClass : ParentClass
{
public new string Target
{
get{return "";}
}
}
}

What I am trying to do is get the property Target from the ChildClass. When
I do the GetProperty I am returned two PropertyInfo objects matching Target -
one from ParentClass and one from ChildClass. This happens because I am
changing the return type of Target from object to string in the ChildClass.
If the return type stays the same then only one PropertyInfo is returned.

Unfortunately, it's not an option for me to make the return types the same.
It's code written by someone else in a fairly big system and would likely
cause all sorts of problems. Has anyone got any suggestions how I can just
get the Target PropertyInfo from the ChildClass?

It's not feasible to use the declaring type attribute of property info as
there are many other classes in my real world code between ChildClass and
ParentClass that I haven't added to the example above.

I've also taken a look at the BindingFlags attribute parameter, but there is
no suitable BindingFlag that will return me the very top level Target object
- the closest is BindingFlags.DeclaredOnly, but this won't return me the
Target if I then inherit from ChildClass but then don't override the Target
object.

I hope I have explained this well, it's kinda difficult to get your head
round.

Any help would be much appreciated.

Stu
Dec 1 '05 #1
15 11133
Try calling GetProperties instead of GetProperty. Then loop through the
returned array and find the property you want.

Thi

Dec 1 '05 #2
Thanks for the quick reply,

I thought about using that but there are several problems. Obviously they
both have the same name, so I have to look at other properties on the
PropertyType attribute to get the right one, however, the candidates for this
would be...

1) Property Type property - I don't know what the return type of the
property is going to be so can't check against that, there are loads of
classes that implement the 'Parent Class', all with different return types.

2) Declaring Type Property - This is the type that the property is declared
in, so if I inherit from ChildClass and don't redefine the Target property,
the declaring type will be ChildClass and not the Type of the object I am
reflecting.

What I need to do, is somehow loop around the class hierarchy and find the
class at the highest (or lowest depending on how you look at it) level that
declares the Target property, but I don't know how without it being messy...

"Truong Hong Thi" wrote:
Try calling GetProperties instead of GetProperty. Then loop through the
returned array and find the property you want.

Thi

Dec 1 '05 #3
I've ended up doing this... I think it works right, it just looks messy...

using System;
using System.Reflection;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//throws an AmbiguousMatchException
Type oType = typeof(SubChildClass);
System.Reflection.PropertyInfo[] oPis = oType.GetProperties();

System.Reflection.PropertyInfo oRequiredPi = null;

int nHierarchyLevel = -1;

foreach(PropertyInfo oPi in oPis)
{
if(oPi.Name=="Target")
{
//examine the basetypes, counting how many times we go up the hierarchy
int nTempHierarchyLevel = GetHierarchyLevel(oPi.DeclaringType, oType, 0);
if((nTempHierarchyLevel<=nHierarchyLevel)||(nHiera rchyLevel==-1))
{
nHierarchyLevel = nTempHierarchyLevel;
oRequiredPi = oPi;
}
}
}
}

private static int GetHierarchyLevel(Type tDeclaringType, Type
tTypeToMatch, int nHierarchyCount)
{
if(tDeclaringType==tTypeToMatch)
{
return nHierarchyCount;
}
else
{
nHierarchyCount++;
return GetHierarchyLevel(tDeclaringType, tTypeToMatch.BaseType,
nHierarchyCount);
}
}
}

//Parent Class
class ParentClass
{
public virtual object Target
{
get{return new object();}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class ChildClass : ParentClass
{
public new string Target
{
get{return "";}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class SubChildClass : ChildClass
{

}
}
"satankidneypie" wrote:
Thanks for the quick reply,

I thought about using that but there are several problems. Obviously they
both have the same name, so I have to look at other properties on the
PropertyType attribute to get the right one, however, the candidates for this
would be...

1) Property Type property - I don't know what the return type of the
property is going to be so can't check against that, there are loads of
classes that implement the 'Parent Class', all with different return types.

2) Declaring Type Property - This is the type that the property is declared
in, so if I inherit from ChildClass and don't redefine the Target property,
the declaring type will be ChildClass and not the Type of the object I am
reflecting.

What I need to do, is somehow loop around the class hierarchy and find the
class at the highest (or lowest depending on how you look at it) level that
declares the Target property, but I don't know how without it being messy...

"Truong Hong Thi" wrote:
Try calling GetProperties instead of GetProperty. Then loop through the
returned array and find the property you want.

Thi

Dec 1 '05 #4
>2) Declaring Type Property - This is the type that the property is declared
in, so if I inherit from ChildClass and don't redefine the Target property,
the declaring type will be ChildClass and not the Type of the object I am
reflecting.

Does DeclaringType.IsAssignableFrom(typeof(ChildClass)) help?

Dec 1 '05 #5
Use the following to only look at the property at the current class scope
(i.e. ChildClass):

System.Reflection.PropertyInfo oPi =
typeof(ChildClass).GetProperty("Target",
System.Reflection.BindingFlags.DeclaredOnly);

Marc

"satankidneypie" <sa************@discussions.microsoft.com> wrote in message
news:01**********************************@microsof t.com...
Hi,

I'm going to start this off with some code as it'll make it easier to
explain afterwards...

using System;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//throws an AmbiguousMatchException
System.Reflection.PropertyInfo oPi =
typeof(ChildClass).GetProperty("Target");
}
}

//Parent Class
class ParentClass
{
public virtual object Target
{
get{return new object();}
}
}

//Child class which inherits from Parent class and hides inherited member
Target with the new keyword, and also changes the return type
class ChildClass : ParentClass
{
public new string Target
{
get{return "";}
}
}
}

What I am trying to do is get the property Target from the ChildClass.
When
I do the GetProperty I am returned two PropertyInfo objects matching
Target -
one from ParentClass and one from ChildClass. This happens because I am
changing the return type of Target from object to string in the
ChildClass.
If the return type stays the same then only one PropertyInfo is returned.

Unfortunately, it's not an option for me to make the return types the
same.
It's code written by someone else in a fairly big system and would likely
cause all sorts of problems. Has anyone got any suggestions how I can just
get the Target PropertyInfo from the ChildClass?

It's not feasible to use the declaring type attribute of property info as
there are many other classes in my real world code between ChildClass and
ParentClass that I haven't added to the example above.

I've also taken a look at the BindingFlags attribute parameter, but there
is
no suitable BindingFlag that will return me the very top level Target
object
- the closest is BindingFlags.DeclaredOnly, but this won't return me the
Target if I then inherit from ChildClass but then don't override the
Target
object.

I hope I have explained this well, it's kinda difficult to get your head
round.

Any help would be much appreciated.

Stu

Dec 1 '05 #6
Seems I put things in wrong order, should be:
typeof(ChildClass).IsAssignableFrom(property.Decla ringType)

Dec 1 '05 #7
Whoops!
I meant:

System.Reflection.BindingFlags.DeclaredOnly |
System.Reflection.BindingFlags.GetProperty |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance

as the binding flags... I didn't realise at the time because the exception
went away and the code ran to completion... I didn't notice that oPi was
null... it works now, however...

Marc

"Marc Gravell" <mg******@rm.com> wrote in message
news:Od**************@TK2MSFTNGP11.phx.gbl...
Use the following to only look at the property at the current class scope
(i.e. ChildClass):

System.Reflection.PropertyInfo oPi =
typeof(ChildClass).GetProperty("Target",
System.Reflection.BindingFlags.DeclaredOnly);

Marc

"satankidneypie" <sa************@discussions.microsoft.com> wrote in
message news:01**********************************@microsof t.com...
Hi,

I'm going to start this off with some code as it'll make it easier to
explain afterwards...

using System;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//throws an AmbiguousMatchException
System.Reflection.PropertyInfo oPi =
typeof(ChildClass).GetProperty("Target");
}
}

//Parent Class
class ParentClass
{
public virtual object Target
{
get{return new object();}
}
}

//Child class which inherits from Parent class and hides inherited member
Target with the new keyword, and also changes the return type
class ChildClass : ParentClass
{
public new string Target
{
get{return "";}
}
}
}

What I am trying to do is get the property Target from the ChildClass.
When
I do the GetProperty I am returned two PropertyInfo objects matching
Target -
one from ParentClass and one from ChildClass. This happens because I am
changing the return type of Target from object to string in the
ChildClass.
If the return type stays the same then only one PropertyInfo is returned.

Unfortunately, it's not an option for me to make the return types the
same.
It's code written by someone else in a fairly big system and would likely
cause all sorts of problems. Has anyone got any suggestions how I can
just
get the Target PropertyInfo from the ChildClass?

It's not feasible to use the declaring type attribute of property info as
there are many other classes in my real world code between ChildClass and
ParentClass that I haven't added to the example above.

I've also taken a look at the BindingFlags attribute parameter, but there
is
no suitable BindingFlag that will return me the very top level Target
object
- the closest is BindingFlags.DeclaredOnly, but this won't return me the
Target if I then inherit from ChildClass but then don't override the
Target
object.

I hope I have explained this well, it's kinda difficult to get your head
round.

Any help would be much appreciated.

Stu


Dec 1 '05 #8
Hi Marc,

If you then inherit from ChildClass with SubChildClass, but don't override
'Target', then Poperty info will be null (Example below)... I have classes
that do this too to contend with... (I am still doing it with the way I said
in one of my postings above - my third posting down I think)

This code returns null for the property info :

using System;
using System.Reflection;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//throws an AmbiguousMatchException
Type oType = typeof(SubChildClass);
PropertyInfo oPi = oType.GetProperty("Target", BindingFlags.DeclaredOnly
| BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
}
}

//Parent Class
class ParentClass
{
public virtual object Target
{
get{return new object();}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class ChildClass : ParentClass
{
public new string Target
{
get{return "";}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class SubChildClass : ChildClass
{

}
}

Dec 1 '05 #9
You are right - sorry, I looked more at the code you provided than the
problem statement (my bad).

How about something like the following (written outside of the IDE, so no
guarantee it will compile, but you get the idea)
Type type = typeof(Whatever);
PropertyInfo pi = null;
while(type!=null && pi!=null) {
pi = type.GetProperty(); // params omitted for brevity, using DeclaredOnly
type = type.BaseType;
}
// pi is now either null or the "highest" version of the property

No idea if it would be quicker or not, but at least it is fairly obvious
what it is doing...

Marc

"satankidneypie" <sa************@discussions.microsoft.com> wrote in message
news:1D**********************************@microsof t.com...
Hi Marc,

If you then inherit from ChildClass with SubChildClass, but don't override
'Target', then Poperty info will be null (Example below)... I have classes
that do this too to contend with... (I am still doing it with the way I
said
in one of my postings above - my third posting down I think)

This code returns null for the property info :

using System;
using System.Reflection;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//throws an AmbiguousMatchException
Type oType = typeof(SubChildClass);
PropertyInfo oPi = oType.GetProperty("Target", BindingFlags.DeclaredOnly
| BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
}
}

//Parent Class
class ParentClass
{
public virtual object Target
{
get{return new object();}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class ChildClass : ParentClass
{
public new string Target
{
get{return "";}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class SubChildClass : ChildClass
{

}
}

Dec 1 '05 #10
of course I mean while(type!=null && pi==null)

(time to get either some sleep or coffee... I guess it'll be the coffee...)

Marc

"Marc Gravell" <mg******@rm.com> wrote in message
news:Oy*************@TK2MSFTNGP15.phx.gbl...
You are right - sorry, I looked more at the code you provided than the
problem statement (my bad).

How about something like the following (written outside of the IDE, so no
guarantee it will compile, but you get the idea)
Type type = typeof(Whatever);
PropertyInfo pi = null;
while(type!=null && pi!=null) {
pi = type.GetProperty(); // params omitted for brevity, using
DeclaredOnly
type = type.BaseType;
}
// pi is now either null or the "highest" version of the property

No idea if it would be quicker or not, but at least it is fairly obvious
what it is doing...

Marc

"satankidneypie" <sa************@discussions.microsoft.com> wrote in
message news:1D**********************************@microsof t.com...
Hi Marc,

If you then inherit from ChildClass with SubChildClass, but don't
override
'Target', then Poperty info will be null (Example below)... I have
classes
that do this too to contend with... (I am still doing it with the way I
said
in one of my postings above - my third posting down I think)

This code returns null for the property info :

using System;
using System.Reflection;

namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[STAThread]
static void Main(string[] args)
{
//throws an AmbiguousMatchException
Type oType = typeof(SubChildClass);
PropertyInfo oPi = oType.GetProperty("Target", BindingFlags.DeclaredOnly
| BindingFlags.GetProperty | BindingFlags.Public |
BindingFlags.Instance);
}
}

//Parent Class
class ParentClass
{
public virtual object Target
{
get{return new object();}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class ChildClass : ParentClass
{
public new string Target
{
get{return "";}
}
}

//Child class which inherits from Parent class and hides inherited member
Target, and also changes the return type
class SubChildClass : ChildClass
{

}
}


Dec 1 '05 #11
>I am still doing it with the way I said
in one of my postings above - my third posting down I think

Have you tried Type.IsAssignableFrom as I suggested? It is much simpler
than the way you do with GetHierarchyLevel.
// Determine if typeToCheck is type1 or a subclass of type1
private bool IsSelfOrChild(Type type1, Type typeToCheck)
{
return type1.IsAssignableFrom(typeToCheck) ;
}

Thi

Dec 2 '05 #12
If I understand the original question correctly (which, admittedly, I didn't
at first), this is more an issue of getting the highest-level version of a
property on aclass-hierarchy (where multiple of the same name may exist via
the new operator, and the top-most class may not define it itself at all).

Given this, I'm not sure that IsAssignableFrom helps much; if it was a case
of getting the correctly typed version, then this can be done using one of
the overloads of GetProperty (that accepts a Type to represent the declared
typ).

Marc

"Truong Hong Thi" <th*****@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
I am still doing it with the way I said
in one of my postings above - my third posting down I think

Have you tried Type.IsAssignableFrom as I suggested? It is much simpler
than the way you do with GetHierarchyLevel.
// Determine if typeToCheck is type1 or a subclass of type1
private bool IsSelfOrChild(Type type1, Type typeToCheck)
{
return type1.IsAssignableFrom(typeToCheck) ;
}

Thi

Dec 2 '05 #13
As I understand, what the OP wanted is that:
- if call with ChildClass, get the Target property as defined in
ChildClass
- if call with SubChildClass and SubChildClass does not override
Target, get the Target property as defined in ChildClass
- if call with SubChildClass and SubChildClass overrides Target, get
the Target property as defined in SubChildClass
- Never get the Target property defined in ParentClass (which
ChildClass extends).

Thus, he could write it as simple as this:
PropertyInfo GetTargetProperty(Type t)
{
if (typeof(ChildClass).IsAssignableFrom(t))
{
// not ChildClass or one of its children
return null;
}

return t.GetProperty("Target");
}

Because the original poster decide to get all properties, and walk the
hierachy to see if a class is a child of other class, he can also
obtain that by simply call IsAssgnableFrom.

Thi

Dec 2 '05 #14
Sorry, I forget to put "!" in the first if, and wrongly called
GetProperty instead of GetProperties as I suggested in my first reply.

Here is the updated version. I should work.
I tested in my machine.

PropertyInfo GetTargetProperty(Type t)
{
if (!typeof(Type1).IsAssignableFrom(t))
{
// not ChildClass or one of its children
return null;
}

PropertyInfo[] ps = t.GetProperties();
foreach (PropertyInfo p in ps)
{
if (p.Name == "Target" && p.PropertyType == typeof(string))
{
return p;
}
}

// not found, return nul
return null;
}

Thi

Dec 2 '05 #15
Hi Stu,

Check out this article on Reflection, it might help you answer your
question.

http://www.developersdex.com/gurus/articles/739.asp

Happy Coding,

Stefan
C# GURU
www.DotNETovation.com

*** Sent via Developersdex http://www.developersdex.com ***
Dec 3 '05 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Steve | last post by:
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...
6
by: Laser Lu | last post by:
HI, all, I just want to invoke an internal method named 'ResolveClientUrl', which is defined in class System.Web.UI.Control, using an instance object of a type that derives from Control. Let's...
4
by: Nicolas | last post by:
The lat part is not working why ???????? Please help......... using System; namespace ConsoleApplication4 {
11
by: Aaron Queenan | last post by:
Given the classes: class Class { public static implicit operator int(Class c) { return 0; } } class Holder
0
by: John Wright | last post by:
I have the following code that creates a new appDomain and loads an exe using reflection. The problem I have is the exe file I pass in is still locked by the application. I have showcopyfiles =...
0
by: Marc Vangrieken | last post by:
Hi, I ran into a strange problem a few days ago; when i execute the code at the bottom of this message GetCustomAttributes() isn't returning anything. Although the attributes are there... The...
7
by: BK | last post by:
I've used reflection quite a bit to launch forms, it works great, requires little coding, and allows me to launch forms from a dynamic menu. Now I have a need to instantiate any one of several...
5
by: Nightfall | last post by:
Dear friends, consider the following scenario, in Visual Studio 2005 and C# - I create a ASP.NET web service ("server") with a class MyClass and a WebMethod SomeMethod() - I create a client...
3
balabaster
by: balabaster | last post by:
Why does this work in C# class test { public double Value { get; set; }
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.