Lets say you have:
PropertyInfo propInfo; // Assume it was already initialized with property of a private field
(private int m_Number)
If I'll do propInfo.PropertyType.Name I guess I will get something like int32 or int.
Two questions:
1. How can I extract the variable name "m_Number" through propInfo.
Note: Once I was able to do so by iterating a FieldInfo instead of propInfo.
2. If I want to use reflection to know all kind of fields of a given class, what should be the right way:
A. Iterating over all properties(in assumption every field has a property)
B. Iterating over all the fields directely.
Thanks
A property is not necessarily related to a field - in fact, a property is a little more than a syntactic sugar on top of a pair of functions.
If your code uses some sort of a convention for naming variables that back properties (such as prepending them with m_, as in your example) you could rely upon that convention to retrieve the variable name. In all other cases, there is no direct connection, and no way to retrieve that relationship through the reflection API.
Related
So I have this.
private int _SomeDataBaseField_;
public int ID
{
get { return _SomeDataBaseField_; }
set { _SomeDataBaseField_ = value; }
}
What I am trying to do is map the property name and the private field name in a way that I can pull the private field name using the property name only and without using any attributes or tags.
So my question is:
Is there any way to deduce the private field name using only the property name? Something like
string PrivateFieldName = typeof(T).GetProperty("ID").GetPrivateFieldName();
Where PrivateFieldName would be SomeDataBaseField.
I tried to use reflection but no luck.. This is as far as I got and it only shows the private field type (Int32) which is not very helpful.
foreach (PropertyInfo item in typeof(T).GetProperties())
{
LocalVariableInfo lv = item.GetAccessors()[0].GetMethodBody().LocalVariables[0];
}
Edit:
I feel I need to explain why I need this.
So I have a class that contains 1200+ properties and they all have private fields (backing fields). now I already spent countless hours creating the mysql database table for that class and now that I am using it I realized that I am going to have to manually type the field name every time I need to update one of the fields in the database. So I thought I would use the private field name as a database column and then supply the update function with the property name which would then look up some collection of <'PropertName, PrivateName'> for the corresponding private field name and use that as the database field name. This would not only save time but it would also limit the need for typing the field names over and over again whenever they need to be updated or parsed.
Thanks in advance.
Use typeof(T).GetFields instead.
A Property in C# is a logical grouping of two CLR Methods (a getter and a setter). A property does not necessarily have a single backing field - it doesn't have to have any, or it could have multiple. You shouldn't make that assumption.
Not every property is backed by a single field - all variants 0-infinity are possible, so you need to review what your goals are.
Proper way would be to parse IL of each property get/set pair and find what (if any) packing field their are using. Such approach would let you detect non-trivial properties that use more than one backing field (or none at all). GetMethodBody is starting point for such code - some info can be found in Can I use reflection to inspect the code in a method?
More practical way would be to rely on some sort of convention to find matches.
I.e. for auto-properties compiler generates predictable names (implementation-dependent) and you can find matching field as shown in Is it possible to access backing fields behind auto-implemented properties?.
For other cases there is usually some naming convention - i.e. field with same name but different case/prefix/suffix. Basic string matching would help for such cases.
I have three different classes:
Task
Order
Transmission
Each class have properties with different types. Also, there is a possibility to attach data that represented by custom fields (implemented by an array of IField, where IField can be text field or list field). Each custom field have a name that represent the name of the attached data property.
I need to convert between each class to another:
Task -> Order
Order -> Transmission
Transmission -> Task
Transmission -> Order
Order -> Task
Task -> Transmission
for that I created:
Static class of static keys where each key represents the name of
the property.
"DataObject" that holds a dictionary of a property name and an object as its value.
Each class (Task, Order, Transmission) implements IDataShare interface:
public interface IDataShare
{
DataObject ToDataObject();
void FromDataObject(DataObject data);
}
For example, task objects with the following properties:
WorkerId:5
CustomerId:7
VehicleId:null
StartDate:null
And with the following custom fields:
Subcontractor: {listId:5, Value:4} (this is list field)
delivery Note: "abc" (this is text field)
will be convert to the following dictionary:
{"WorkerId", 5}
{"CustomerId", 7}
{"VehicleId", null}
{"StartDate", null}
{"Subcontractor", {listId:5, Value:4}}
{"delivery Note", "abc"}
the string keys "WorkerId", "CustomerId", "VehicleId", "StartDate" were taken from static class that contains string consts where "Subcontractor" and "deliveryNote" are the names of the custom fields the user added (I don't know which fields the user might add so I just use the field name).
When I fill an object using DataObject I have to verify the name of the property is the same as the name of the key and also verify the value is correct (string cannot inserted into long).
In addition, custom list field (subcontractor) can't have only itemId as a value because when I have to verify that the listId of the custom field in the object is the same with the listId of the customField in the DataObject.
I have many problems about knowing the type of the value. I always have to use "X is Y" if statements of "X as Y" statements. In addition, I have to remember how to store the type of the value when implementing IDataShare interface which makes the work harder.
Can anyone help me think about constraint I can add to the conversion proccess from an object to DataObject? Can anyone help me improve this method of converting objects?
Thanks!
UPDATE
I want to explain a point. My biggest problem is that there are several ways to translate each property/custom field so I need to remember the type of the value in DataObject. For example, in Transmission class I have VehicleId property. I want to convert Task object with custom field with the name "VehicleId" to Transmission. All I want is that Task's custom field VehicleId's value will be converted into the VehicleId property of Transmission. But, because it is custom field - as I wrote before - there is a way I store custom field that based on a list: {listId:5, Value:4}. Now, in the conversion proccess (FromDataObject in Transmission) in case the DataObject has "VehicleId" key, I have to check whether the value is long (vehicle id as property) or IListField (vehicle id as custom list field).
those type checking really makes mess.
Well, if the number of classes you're converting between is really as limited as you've said, may I suggest just writing casting operators for your classes?
http://msdn.microsoft.com/en-us/library/xhbhezf4%28v=VS.100%29.aspx
It seems like the amount of logic that you're putting into the conversion is enough to warrant something like this.
On the other hand, it seems like there is a base set of fields being used across the different objects and you're just stuffing them into an untyped dictionary. If the fields are common across all types, could you use a conversion to a strongly typed common object?
Which also begs the question: could you use a common base class object?
If you have options of modifying the Task, Order, and Transmission definitions, I'd take a look at them again. This sort of scenario seems like a "code smell".
If I understand this correctly ToDataObjectis basically a serializer and FromDataObject is a deserializer. If the data contained by these object is type compatible, then it seems that the very act of serializing it into untyped data is the source of your problem. Why do this, instead of just keeping the data in its native format?
If you need to use an adapter because there are incompatibilities between the objects that can't be resolved for some reason, I would think that you can make one that at least keep the data in its native structures instead of serializing everything to a string. A dictionary in C# can contain anything, at a minimum you could be using a Dictionary<string,object>.
It's also unclear what all this verification is about - why would data be incompatible, if you are mapping properties of the same data types? E.g. assuming that this is an internal process, under what circumstance could (e.g.) a string from one object be trying to be assigned to a long in another object? Seems that would only be necessary if the data were strongly typed in one object, but not in another.
Have you considered using generics?
If Task, Order and Transmission all inherit from a base class like Property, then you could expose a common method for getting the values you need.
GetMyValue() where T : Property
It's not very clear what you are trying to achieve.
I'm doing some dynamic code generation using Reflection, and I've come across a situation where I need to get the backing field of a property (if it has one) in order to use its FieldInfo object.
Now, I know you can use
.IsDefined(typeof(CompilerGeneratedAttribute), false);
on a FieldInfo to discover whether it's autogenerated, so I assume there's a similar thing for Properties which auto-generate fields?
Cheers, Ed
The get_ and set_ methods for properties also get the CompilerGeneratedAttributed applied to them. While there is no strong coupling through attributes, there is a naming convention used for the backing fields of an auto property:
public string Foo { get; set;}
Produces a private string <Foo>k__BackingField member (the < and > here are part of the name, as they're legal in IL but not in C#; they have nothing to do with generics).
As an example, this will get a list of all of the auto properties in a class, along with their backing fields:
t.GetProperties().Where(p =>
(p.GetGetMethod() ?? p.GetSetMethod()).IsDefined(typeof(CompilerGeneratedAttribute), false))
.Select(p => new
{
Property = p,
Field = t.GetField(string.Format("<{0}>k__BackingField", p.Name),
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
});
There is no built-in method for doing this since the presence of a property does not necessarily guarantee the presence of a backing field.
I found this article which explains one way of doing it. It involves getting the IL of the property's setter and parsing it looking for evidence of a field being set.
Andrew is right.
Actually, a property is just a "pointer" to methods, usually getters/setters when they are generated by Visual Studio or other high level language (most of the time).
Parsing the setter is not easy, though. And, since internally setters are just another vanilla methods, they can use more than one fields, or none at all, or even call another methods.
Perhaps you can come up with a solution for the common scenarios, but you have to parse the IL bytecode.
I am warpping an ArcGIS IFeature object with a class that has my required properties to get and set them easily.
Basically, the get and set operations just use feature.get_value(index) and feature.set_value(indes, value), and expose the strongly typed value.
I have several fields that use a domain (basically, an IDictionary<string, object>) to represent common properties across the application.
At first I figured I would only use the keys of the domain (which are normal int values) in my wrapping class, and use the domain in my ToString() method, to translate to strings for the UI.
Later I figured out I can use strings in my applicaiton (which makes it easier to pass around nulls, as the actual domain fields are nullable most of the time), and only change those fields' getters and setters to use GetDomainValue(index) and SetDomainValue(index, value) method that will translate between the key and value to/from the underlying feature object.
What approach do you think is better? I figured the string approach is a bit more "persistent ignorant", as my class doesn't care how the values are being saved, just their string representation.
On the other hand, it makes the code jump through loops a bit - instead of returning what's in the feature, every getter needs to iterate the domain.
You might want to think about representing your domain fields with Nullable< Int32>. This would give you a way to represent features that have a domain value specified but it also allows you to directly specify null where appropriate.
I ended up sticking with the domain values, so that I can also verify that the calling code passed a valid value.
Quick question: When do you decide to use properties (in C#) and when do you decide to use methods?
We are busy having this debate and have found some areas where it is debatable whether we should use a property or a method. One example is this:
public void SetLabel(string text)
{
Label.Text = text;
}
In the example, Label is a control on a ASPX page. Is there a principle that can govern the decision (in this case) whether to make this a method or a property.
I'll accept the answer that is most general and comprehensive, but that also touches on the example that I have given.
From the Choosing Between Properties and Methods section of Design Guidelines for Developing Class Libraries:
In general, methods represent actions and properties represent data. Properties are meant to be used like fields, meaning that properties should not be computationally complex or produce side effects. When it does not violate the following guidelines, consider using a property, rather than a method, because less experienced developers find properties easier to use.
Yes, if all you're doing is getting and setting, use a property.
If you're doing something complex that may affect several data members, a method is more appropriate. Or if your getter takes parameters or your setter takes more than a value parameter.
In the middle is a grey area where the line can be a little blurred. There is no hard and fast rule and different people will sometimes disagree whether something should be a property or a method. The important thing is just to be (relatively) consistent with how you do it (or how your team does it).
They are largely interchangeable but a property signals to the user that the implementation is relatively "simple". Oh and the syntax is a little cleaner.
Generally speaking, my philosophy is that if you start writing a method name that begins with get or set and takes zero or one parameter (respectively) then it's a prime candidate for a property.
Searching through MSDN, I found a reference on Properties vs Methods that provides some great guidelines for creating methods:
The operation is a conversion, such as Object.ToString.
The operation is expensive enough that you want to communicate to the
user that they should consider caching
the result.
Obtaining a property value using the get accessor would have an observable
side effect.
Calling the member twice in succession produces different results.
The order of execution is important. Note that a type's properties should
be able to be set and retrieved in any
order.
The member is static but returns a value that can be changed.
The member returns an array. Properties that return arrays can be
very misleading. Usually it is
necessary to return a copy of the
internal array so that the user cannot
change internal state. This, coupled
with the fact that a user can easily
assume it is an indexed property,
leads to inefficient code.
If you're setting an actual property of your object then you use a property.
If you're performing a task / functionality then you use a method.
In your example, it is a definite property being set.
If however, your functionality was to AppendToLabel then you would use a method.
Properties are a way to inject or retrieve data from an object. They create an abstraction over variables or data within a class. They are analogous to getters and setters in Java.
Methods encapsulate an operation.
In general I use properties to expose single bits of data, or small calculations on a class, like sales tax. Which is derived from the number of items and their cost in a shopping cart.
I use methods when I create an operation, like retrieving data from the database. Any operation that has moving parts, is a candidate for a method.
In your code example I would wrap it in a property if I need to access it outside it's containing class:
public Label Title
{
get{ return titleLabel;}
set{ titleLabel = value;}
}
Setting the text:
Title.Text = "Properties vs Methods";
If I was only setting the Text property of the Label this is how I would do it:
public string Title
{
get{ return titleLabel.Text;}
set{ titleLabel.Text = value;}
}
Setting the text:
Title = "Properties vs Methods";
Symantically properties are attributes of your objects.
Methods are behaviors of your object.
Label is an attribute and it makes more sense to make it a property.
In terms of Object Oriented Programming you should have a clear understanding of what is part of behavior and what is merely an attribute.
Car { Color, Model, Brand }
A car has Color, Model and Brand attributes therefore it does not make sense to have a method SetColor or SetModel because symantically we do not ask Car to set its own color.
So if you map the property/method case to the real life object or look at it from symantic view point, your confusion will really go away.
You need only look at the very name... "Property". What does it mean? The dictionary defines it in many ways, but in this case "an essential or distinctive attribute or quality of a thing" fits best.
Think about the purpose of the action. Are you, in fact, altering or retrieving "an essential or distinctive attribute"? In your example, you are using a function to set a property of a textbox. That seems kind of silly, does it not?
Properties really are functions. They all compile down to getXXX() and setXXX(). It just hides them in syntactic sugar, but it's sugar that provides a semantic meaning to the process.
Think about properties like attributes. A car has many attributes. Color, MPG, Model, etc.. Not all properties are setable, some are calculatable.
Meanwhile, a Method is an action. GetColor should be a property. GetFile() should be a function. Another rule of thumb is, if it doesn't change the state of the object, then it should be a function. For example, CalculatePiToNthDigit(n) should be a function, because it's not actually changing the state of the Math object it's attached to.
This is maybe rambling a bit, but it really boils down to deciding what your objects are, and what they represent. If you can't figure out if it should be a property or function, maybe it doesn't matter which.
Properties should only be simple set and get one liners. Anything more and it should really be moved to a method. Complex code should always be in methods.
I only use properties for variable access, i.e. getting and setting individual variables, or getting and setting data in controls. As soon as any kind of data manipulation is needed/performed, I use methods.
As a matter of design Properties represent Data or Attributes of class object, While methods are actions or behaviors of class object.
In .Net, world there are other implications of using Properties:
Properties are used in Databinding, while get_ / set_ methods are not.
XML serialization user properties as natural mechanism of serilization.
Properties are accessed by PropertyGrid control and intern ICustomTypeDescriptor, which can be used effectively if you are writing a custom library.
Properties are controlled by Attributes, one can use it wisely to design Aspect Oriented softwares.
Misconceptions (IMHO) about Properties' usage:
Used to expose small calculations: ControlDesigner.SelectionRules's get block runs into 72 lines!!
Used to expose internal Data structures: Even if a property does not map to an internal data member, one can use it as property, if its an attribute of your class. Viceversa, even if its an attribute of your class properties are not advisable, to return array like data members (instead methods are used to return deep copy of members.)
In the example here it could have been written, with more business meaning as:
public String Title
{
set { Label.Text = text; }
}
Also big plus for Properties is that value of property can be seen in Visual Studio during debugging.
I prefer to use properties for add/set methods with 1 parameter. If parameters are more, use methods.
Properties are really nice because they are accessible in the visual designer of visual studio, provided they have access.
They use be used were you are merely setting and getting and perhaps some validation that does not access a significant amount of code. Be careful because creating complex objects during validation is not simple.
Anything else methods are the preferred way.
It's not just about semantics. Using properties inappropriate start having weirdness occur in the visual studio visual designer.
For instance I was getting a configuration value within a property of a class. The configuration class actually opens a file and runs an sql query to get the value of that configuration. This caused problems in my application where the configuration file would get opened and locked by visual studio itself rather than my application because was not only reading but writing the configuration value (via the setter method). To fix this I just had to change it to a method.
Here is a good set of guidelines for when to use properties vs methods from Bill Wagner
Use a Property when all these are true:
The getters should be simple and thus unlikely to throw exceptions. Note that this implies no network (or database) access. Either might fail, and therefore would throw an exception.
They should not have dependencies on each other. Note that this would include setting one property and having it affect another. (For example, setting the FirstName property would affect a read-only FullName property that composed the first name + last name properties implies such a dependency )
They should be settable in any order
The getter does not have an observable side effect Note this guideline doesn't preclude some forms of lazy evaluation in a property.
The method must always return immediately. (Note that this precludes a property that makes a database access call, web service call, or other similar operation).
Use a method if the member returns an array.
Repeated calls to the getter (without intervening code) should return the same value.
Repeated calls to the setter (with the same value) should yield no difference from a single call.
The get should not return a reference to internal data structures (See item 23). A method could return a deep copy, and could avoid this issue.
*Taken from my answer to a duplicate question.
This is simple.
1: use property when you want your data should be validated before storing in field. So in this way property provides encapsulation for your fields. Because if you leave your fields public end user may assign any value which may or may not be valid as per your business requirement like age should be greater than 18. So before value is store corresponding field we need to check its validity. In this way properties represent data.
2: Use method when you want perform some action like you are supplying some data as parameter and your method is doing some processing on the basis of supplied values and returning processed value as output. Or you want to change value of some field by this calculation. "In this way method represents action".
I come from java an i used get.. set.. method for a while.
When i write code, i don't ask to my self: "accessing this data is simple or require a heavy process?" because things can change (today retrive this property is simple, tomonrow can require some or heavy process).
Today i have a method SetAge(int age) tomonrow i will have also method SetAge(date birthdate) that calculate the age using the birthdate.
I was very disappointed that the compiler transform property in get and set but don't consider my Get... and Set.. methods as the same.