C# Reflection Help? (GetProperties) - c#

My code is returning a blank array of PropertyInfo
PropertyInfo[] classProperties = typeof(Processor).GetProperties();
All properties in this class are public.
Using .NET 2.0 Framework.
I have also tried using an instance declared earlier in my code:
PropertyInfo[] classProperties = Computer.Processor[0].GetType().GetProperties();
And I have tried using bindings such as Default, Instance and Public.
Any ideas?

The parameterless form will return public properties. So there are 2 likely options:
they are not properties (but instead, fields)
they are not public
A public property is something a: with the public modifier, and b: with a get or set accessor, for example either of:
public int Foo {get;set;} // automatically implemented property
public string bar;
public string Bar { // manually implemented property
get { return bar; }
set { bar = value; }
}
Note also that interface-bound properties that are implemented as explicit interface implementation will only be reflected if you query against the interface, not the class; so the following will not show unless you start from typeof(ISomeInterface):
string ISomeInterface.Bar { get { return someValue; } }

Related

C# Property with no setter - how can it get set from constructor?

How come you can set a get-only auto-property from a constructor? The code below shows how you can set the property from the constructor but using reflection shows that there really isn't a setter behind the scenes. How does it get set from the constructor call if the setter method doesn't even exist in the IL?
void Main()
{
var obj = new GetOnlyProperty("original value");
Console.WriteLine(obj.Thing); //works, property gets set from ctor
//get the set method with reflection, is it just hidden..?
//nope, null reference exception
typeof(GetOnlyProperty)
.GetProperty("Thing", BindingFlags.Instance | BindingFlags.Public)
.GetSetMethod()
.Invoke(obj, new object[]{"can't set me to this, setter doen't exist!"});
}
public class GetOnlyProperty
{
public string Thing { get; }
public GetOnlyProperty(string thing)
{
Thing = thing;
}
}
A read-only automatically-implemented property is converted by the compiler into a read-only field and a read-only property. Assignments to the property in the constructor are compiled as assignments to the underlying field.
So your code here:
public class GetOnlyProperty
{
public string Thing { get; }
public GetOnlyProperty(string thing)
{
Thing = thing;
}
}
is compiled into IL as if you'd written:
public class GetOnlyProperty
{
private readonly string _thing;
public string Thing => _thing;
public GetOnlyProperty(string thing)
{
_thing = thing;
}
}
... except that _thing is really given an "unspeakable name" that wouldn't be a valid C# identifier.
A read-only property (get only) has a backing readonly field, which as you probably know, can only be set in the constructor.
hence when you have object Property { get; }
this translates to
private readonly object _property;
public object get_Property(){return _property;}
and the compiler knows that if you set the property in the constructor to set the field directly
Because a read-only property should be assigned at a time or another, otherwise its value would always be the default value of the type, and it would be completely useless.
This is what constructors are for (beside other obvious reasons), to assign values to read-only fields.

Understanding different ways of using accessors

For an object sellprint declared as static in the class
private static string sellprint = "";
public string Sellprint
{
get { return sellprint; }
}
public void SetSellprint(string x)
{
sellprint = x;
}
How is this
different from
public string Sellprint
{
get; set;
}
internally.
I could not find any examples of code 1 on msdn. what does it translate into?
The compiler creates a getter method for your property in the first code that returns the value of sellprint field because you implement only the getter method.In the second code, both getter and setter methods creating by compiler and also the backing-field.That's the difference.
You can verify that using ILDASM.exe:
First, consider this code:
class Foo
{
private string _value;
public string Value
{
get { return _value; }
}
public void SetValue(string str)
{
_value = str;
}
}
As you can see there is only one method generated by compiler which is get_Value.
If we change it like this and make the Value an auto-implemented property:
class Foo
{
public string Value { get; set; }
}
You can see that compiler creates both getter (get_Value) and setter (set_Value) method and also create a private backing field for the property.
There is no pros or cons about the functionality except in the second code you are doing the same work with less code.
1) should not work because there is no sellprint - assuming you have a field named sellprint and just forgot in your code snippet, you provide a get accessors and a method instead of the set accessors, which is kinda strange.
2) will create the field required automatically (and will not tell you the name, so you cannot accidentally use it)
There is not difference between those two though.

Do C# properties hide instance variables or is something deeper going on?

Consider the class:
public class foo
{
public object newObject
{
get
{
return new object();
}
}
}
According to MSDN:
Properties are members that provide a flexible mechanism to read,
write, or compute the values of private fields. Properties can be used
as though they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily
And:
Properties enable a class to expose a public way of getting and
setting values, while hiding implementation or verification code.
A get property accessor is used to return the property value, and a
set accessor is used to assign a new value. These accessors can have
different access levels. For more information, see Accessor
Accessibility.
The value keyword is used to define the value being assigned by the
set indexer.
Properties that do not implement a set method are read only.
while still providing the safety and flexibility of methods.
Does this therefore mean that at some point in time the value of the newObject property has a reference to the returned new object?
edit removed readonly from property
edit2 also would like to clarify that this is not the best use for a property but its done to try and illustrate the question more effectively.
You return a new object on each access to the property and that is not the expected behavior of properties. Instead you should return the same value each time (e.g. a value stored in a field). A property getter is simply glorified syntax for a method that returns a value. Your code compiles into something like this (the compiler creates a getter by prefixing the property name with get_ which is then emitted as IL):
public class foo
{
public object get_newObject()
{
return new object();
}
}
Each call to the getter will create a new object that foo doesn't know about or has access to.
Does this therefore mean that at some point in time the value of the newObject property has a reference to the returned new object?
No.
Property using a backing field:
class Foo {
readonly Object bar = new Object();
public Object Bar { get { return this.bar; } }
}
Using automatic properties:
class Foo {
public Foo() {
Bar = new Object();
}
public Object Bar { get; private set; }
}
A property is accessed using the same easy syntax as a public field. However, by using a property you can add code to the getter and the setter allowing you to do stuff like lazy loading in the getter or validation in the setter (and much more).
Under the hood, your property will simply be calling a function named get_newObject() that looks like this:
public object get_newObject()
{
return new object();
}
Since that is the case, it will always return a new object every time it is invoked.
If you want to retain a reference to the object, then I would recommend creating a private field to hold the data and having the property access that field, like so:
private object myObject;
public object newObject
{
if(myObject == null)
{
myObject = new object();
}
return myObject;
}
Since your property doesn't define set, and your field is private, newObject is basically eradonly outside of the containing class.
Properties in C# are "syntactic sugar". The code within the get block of a property is in fact put into a hidden get_PropertyName() method, and the set block into a hidden set_PropertyName() method. In the case of your code, the following method will be created:
public object get_newObject()
{
return new object();
}
You can see these hidden methods if you view the compiled assembly using Reflector, or ildasm.
When the property is used, the C# compiler converts any "get" accesses of your property into calls of the get_newObject() method. As an example:
If you were to write the following:
var foo = new foo();
var aNewObject = foo.newObject;
The compiler would convert that to:
var foo = new foo();
var aNewObject = foo.get_newObject();
So, in answer to your other question, the newly created object returned when someone "gets" the property won't be stored within your foo instance, the caller will simply get a new object every time.
Not exactly. Properties are just syntactic sugar so that you don't have to write accessor methods (like Java).
So this:
private int _myInteger;
public int MyInteger
{
get { return _myInteger; }
set { _myInteger = value; }
}
is equivilant to this:
private int _myInteger;
public int GetMyInteger()
{
return _myInteger;
}
public void SetMyInteger(int value)
{
_myInteger = value;
}
and it gets better with this, which is also equivilant:
public int MyInteger { get; set; }

Strange Effect with Overridden Properties and Reflection

I've come across a strange behaviour in .NET/Reflection and cannot find any solution/explanation for this:
class A
{
public virtual string TestString { get; set; }
}
class B : A
{
public override string TestString
{
get { return "x"; }
}
}
Since properties are just pairs of functions (get_PropName(), set_PropName()) overriding only the "get" part should leave the "set" part as it is in the base class. And this is just what happens if you try to instanciate class B and assign a value to TestString, it uses the implementation of class A.
But what happens if I look at the instantiated object of class B in reflection is this:
PropertyInfo propInfo = b.GetType().GetProperty("TestString");
propInfo.CanRead ---> true
propInfo.CanWrite ---> false(!)
And if I try to invoke the setter from reflection with:
propInfo.SetValue("test", b, null);
I'll even get an ArgumentException with the following message:
Property set method not found.
Is this as expected? Because I don't seem to find a combination of BindingFlags for the GetProperty() method that returns me the property with a working get/set pair from reflection.
EDIT:
I would expect that behaviour if I'd use BindingFlags.DeclaredOnly on GetProperties() but the default (BindingFlags.Default) takes inherited members into account and the setter of TestString clearly is inherited!
Here's a workaround:
typeof(B).GetProperty("TestString")
.GetAccessors() // { B.get_TestString() }
.First() // B.get_TestString()
.GetBaseDefinition() // A.get_TestString()
.DeclaringType // typeof(A)
.GetProperty("TestString") // A.TestString: CanRead and CanWrite
This approach should be reasonably robust. You will need to be more careful with this (BindingFlags) if you're looking for non-public accessor(s).
EDIT:
Note that this approach is different from "hardcoding" typeof(A).GetProperty("TestString") or typeof(B).BaseType.GetProperty("TestString") because it finds the actual, original type that declares the property in question. Since it isn't possible (not in C# at least) for a derived type to add new accessors to an overridden property, the property-declaration on this "original" type should contain all the relevant accessors.
You're not overwritting a method, you're overwritting a property definition
The default definition of the property includes Get/Set methods, and your new definition only includes a Get method, so it makes sense that your overwritten property only has Get available, not Set
Edit
If you run something like Reflector on this, you'll see that
class A
{
public virtual string TestString { get; set; }
}
class B : A
{
public override string TestString
{
get { return "x"; }
}
}
compiles into something like that looks like
internal class A
{
// Fields
[CompilerGenerated]
private string <TestString>k__BackingField;
// Methods
public A();
// Properties
public virtual string TestString { [CompilerGenerated] get; [CompilerGenerated] set; }
}
internal class B : A
{
// Methods
public B();
// Properties
public override string TestString { get; }
}
When you set the value in code, you are actually calling something like B.base.set_TestValue. When you reflect something, you are trying to find B.set_TestValue, which doesn't exist.
While true that you cannot overwrite a property, you can overwrite a property definition (providing it doesn't conflict with the base property definition). Since your question was originally tagged with WPF, I was thinking of DependencyProperties at the time, which are actually property definitions, and not properties in the sense that you might be thinking of.

C# pre initialized class

What is the best practice to create pre-initialized class. For example
Chip chip = new Atmega8();
I would like to have its properties already defined like:
chip.Name = "Atmega8 AVR Chip";
and so on.
How to achieve it in C#?
Should I use readonly public properties or property with private set?
Have your constructor initialize the values:
class Atmega8 {
public Atmega8 ()
{
Name = "Atmega8 AVR Chip";
}
public string Name { get; set; }
}
If you intend Name to be the same for all instances, it might make sense to declare it abstract in the base class and override the getter:
abstract class Chip {
public abstract string Name { get; }
}
class Atmega8 : Chip {
public override string Name {
get { return "Atmega8 AVR Chip"; }
}
}
Because we haven't defined a set method, the value cannot be changed, much like a readonly variable except it isn't even stored anywhere and just returned on each call.
If you want the compiler to enforce that nothing can change the value of the field once initialized, then set it up as a read-only field, and populate it in the constructor of the class (or simply initialize it when you declare it; this doesn't work so well with inheritance though). If you don't care as long as nothing OUTSIDE the object can change it (meaning you will trust your own coding discipline to ensure it doesn't change internally), a get-only property with a backing field, or an auto-property with a private setter, are your bets.
IF you absitively posolutely DO NOT WANT the value to change for a particular class, EVER, then I would make it a get-only property returning either a string literal or a constant. I would recommend using the constant over the literal, as you can put the constants into their own static class which you can then use separately from each Chip class.
HOWEVER, there's a quirk of constants you should know. A constant value in .NET is stored in the manifest of not only the assembly containing the declaring code, but in every assembly that references the declaring assembly. Each assembly's code them uses the value from its own manifest. So, if the constant value EVER changes, any assembly that references the declaring assembly must be recompiled to update those assemblies' manifests with the new value. Otherwise, the constant will only have its new value when used from within the declaring assembly. For this reason, labeling a variable as constant should not be done lightly. Personally, my opinion is if the constant isn't some value on which the continued existence and functioning of the universe depends, like pi, e, the speed of light in a vacuum, Plank's Constant, Avogadro's Number, etc, then it isn't "constant". Anything else, like communication code ordinals, CAN change, even if doing so would break compatibility with every previous version of your program.
Depends what you want to accomplish.
It looks like you never want the value of Name to change. One approach would be to declare Name as abstract in Chip, and implement Name in each child class to return a constant string value.
abstract class Chip
{
public abstract string Name { get; }
}
class Amiga8 : Chip
{
public override string Name { get { return "Atmega8 AVR Chip"; } }
}
class Program
{
static void Main(string[] args)
{
Chip chip = new Amiga8();
Console.WriteLine(chip.Name);
}
}
In the constructor of the Atmega8 class you can set a property to something. Ie:
public Atmega8() {
Name = "Atmega8 AVR Chip";
}
If you do not want that to be changed in runtime you could mark the property as readonly ( only assignable through a constructor of declarative ).
private readonly string _Name = string.Empty;
public string Name {
get { return _name; }
}
public Atmega8() {
_Name = "Atmega8 AVR Chip";
}
Value of property cannot change -> Read-only public property.
Value of property can change -> Property with private set
If you don't want it to change, make the Name property a const or readonly on the Atmega8 class. Private set still allows the Name to change internally.
You're saying that you want the class to be populated at the same time it's initialized? Just populate the object in the constructor, like so:
class Test
{
public Test()
{
this.Name = "Hello World";
}
//if you need to pass information into the constructor:
public Test(string testName)
{
this.Name = testName;
}
}
Then, you can do this to initialize it:
Test test = new Test(); //default name of Hello World!
OR
Test test = new Test("Bingo!");

Categories