using attributes vs conventional getting properties - c#

I need to find all properties of a specific object which are not readonly and based on their type do something
I mean if the type of property is int i need to do sth and if it is string i should do something else
using reflection and get this type and conventionally i can create an object which can do what I want
for example if the property type is Int , I can create an instance of IntType:IType class
but I have another option: set an attribute for each property and based on these attributes,find suitable IType
I just cant decide which one is better?

If all the information you need is already contained in the type of the property, I can't see how introducing a new attribute is a good idea. Aside from anything else, you can easily forget to update the attribute when the data type changes. You start off with:
[Int32Type]
int Foo { get; set; }
then find you actually need it to be a long, but forget to change the attribute:
[Int32Type]
long Foo { get; set; }
Now you're probably going to be acting incorrectly on it.
If you're really adding information - e.g. if not all int properties need to be treated the same way - that's a different matter.

Related

Why can't a field itself have getters/setters like properties do?

I'm a C# beginner, so easy explanations are greatly appreciated.
I was learning about properties, and got this question: properties give custom access logic to fields, but why can't the field itself contain its getter/setter? In other words, is there a reason why we can't get rid of Example and write custom get/setters under example(field)?
I could not find other posts that answer my question.
class MyClass
{
private int example = 5;
public int Example
{
get;
private set;
}
// here, this Example property only acts as a gateway for example.
// why is it not possible for the field 'example' to contain the
// get/set?
}
Property is an interface to Class, and not always is about storing data, you can always make the variable public member and will work perfectly like property, but the property has its own main job to work as an interface for that value with other classes.
While in many cases the property just works as public parameters, it is not always meant to be used in that way.

Using value of propertie in his own custom attribute

We use some DTOs in your business logic. I also use these DTOs for printing. So there is a custom attribute printable which will be used in the print-framework to recognize which properties to print. In some cases it is necessary to preformat the value for the printengine.
My idea was to use a construct like this:
[Printable(formatedValue = DoFormatingXY(MyProperty))]
public int MyProperty{ get; set; }
But unfortunatly this will not work (apart from the fact that it is unpleasant to have to use the propertie-name again):
Error An object reference is required for
the non-static field, method, or property '...MyPropertie.get'
So I understand what the problem is, but how can handle it? One idea was to use delegates, but there are a lot of formatting-methods with different method signatures.
Attributes are just metadata, not code. So change it to something like:
[Printable(FormatStyle = FormatStyles.XY)]
public int MyProperty{ get; set; }
Then the printer code can check for a FormatStyle parameter to the attribute and apply the requested format to the property.

Why use private members then use public properties to set them?

Seen a few examples of code where this happens:
public class Foo
{
string[] m_workID;
public string[] WorkID
{
get
{
return m_workID;
}
private set
{
m_workID = value;
}
}
}
What's the point of this?
Since the use m_workID unnescessary.
In general, the point is to separate implementation (the field) from API (the property).
Later on you can, should you wish, put logic, logging etc in the property without breaking either source or binary compatibility - but more importantly you're saying what your type is willing to do, rather than how it's going to do it.
I have an article giving more benefits of using properties instead of public fields.
In C# 3 you can make all of this a lot simpler with automatically implemented properties:
public class Foo
{
public string[] WorkID { get; private set; }
}
At that point you still have a public getter and a private setter, but the backing field (and property implementation) is generated for you behind the scenes. At any point you can change this to a "normal" fully-implemented property with a backing field, and you'll still have binary and source compatibility. (Compatibility of serialized objects is a different matter, mind you.)
Additionally, in this case you can't mirror the behaviour you want (the ability to read the value publicly but write it privately) with a field - you could have a readonly field, but then you could only write to it within the constructor. Personally I wish there were a similar shorthand for this:
public class Foo
{
private readonly int id;
public int Id { get { return id; } }
...
}
as I like immutable types, but that's a different matter.
In another different matter, it's generally not a good idea to expose arrays like this anyway - even though callers can't change which array WorkID refers to, they can change the contents of the array, which is probably not what you want.
In the example you've given you could get away without the property setter, just setting the field directly within the same class, but it would mean that if you ever wanted to add logging etc you'd have to find all those writes.
A property by itself doesn't provide anywhere to put the data - you need the field (m_workID) for storage, but it entirely correct to hide that behind a property for many, many reasons. In C# 3.0 you can reduce this to:
public string[] WorkID {get; private set;}
Which will do much of the same. Note that exposing an array itself may be problematic, as there is no mechanism for protecting data in an array - at least with an IList<string> you could (if needed) add extra code to sanity check things, or could make it immutable. I'm not saying this needs fixing, but it is something to watch.
In addition to the Object Oriented philosophy of data encapsulation, it helps when you need to do something every time your property is read/write.
You can have to perform a log, a validation, or any another method call later in your development.
If your property is public, you'll have to look around all your code to find and modify your code. And what if your code is used as a library by someone else ?
If your property is private with appropriate get/set methods, then you change the get/set and that's all.
You can use C# 3.0 auto properties feature to save time typing:
public class Foo
{
public string[] WorkID
{
get; private set;
}
}
In addition properties gives you lot of advantages in comparison to fields:
properties can be virtual
properties hide implementation details (not all properties are just trivial variable accessors)
properties can contain validation and logging code and raise change events
interfaces cannot contains fields but properties
A lot of times you only want to provide read access to a field. By using a property you can provide this access. As you mention you may want to perform operations before the field is accessed (lazy loading, e.g.). You have a lot of code in there that just isn't necessary anymore unless you're still working in .Net 2.0-.

C# Automatic Properties

I'm a bit confused on the point of Automatic properties in C# e.g
public string Forename{ get; set; }
I get that you are saving code by not having to declare a private variable, but what's the point of a property when you are not using any get or set logic? Why not just use
public string Forename;
I'm not sure what the difference between these 2 statements is, I always thought you used properties if you wanted additional get/set logic?
Properties can have code put into them without breaking contract, fields can't have code put into them without changing them to properties (and breaking the interface). Properties can be read only or write only, fields can't. Properties can be data bound, fields can't.
You can write
public string Forename{ get; private set; }
to get read-only properties... Still not nearly as versatile as real properties, but it's a compromise that for some works.
I'm not sure what the difference between these 2 statements is, I always thought you used properties if you wanted additional get/set logic?
In the first case, the compiler will automatically add a field for you, and wrap the property. It's basically the equivalent to doing:
private string forename;
public string Forename
{
get
{
return this.forename;
}
set
{
this.forename = value;
}
}
There are many advantages to using properties over fields. Even if you don't need some of the specific reasons, such as databinding, this helps to future-proof your API.
The main problem is that, if you make a field, but in v2 of your application, need a property, you'll break the API. By using an automatic property up front, you have the potential to change your API at any time, with no worry about source or binary compatibility issues.
It is meant that you expect to add the logic later.
If you do so and have it as property from the beginning, you will not have to rebuild the dependent code. If you change it from a variable to a property, then you will have to.
Consider looking at some related threads about Difference Between Automatic Properties and Public Fields, Fields vs Properties, Automatic Properties - Useful or Not?, Why Not to Use Public Fields.
Public data members are evil (in that the object doesn't control modification of it's own state - It becomes a global variable). Breaks encapsulation - a tenet of OOP.
Automatic properties are there to provide encapsulation and avoid drudgery of writing boiler plate code for simple properties.
public string ID { get; set;}
You can change automatic properties to non-automatic properties in the future (e.g. you have some validation in a setter for example)... and not break existing clients.
string m_ID;
public string ID
{
get { return m_ID; }
set
{
//validate value conforms to a certain pattern via a regex match
m_ID = value;
}
}
You cannot do the same with public data attributes. Changing a data attribute to a property will force existing clients to recompile before they can interact again.
When adding auto properties the compiler will add get set logic into the application, this means that if you later add to this logic, and references to your property from external libraries will still work.
If you migrated from a public variable to a property, this would be a breaking change for other libraries that reference yours - hence, why not start with an auto property? :)
For one, you can set the property to virtual and implement logic in an inheriting class.
You can also implement logic in the same class afterwards and there won't be side-effects on any code relying on the class.
Not all properties need get/set logic. If they do, you use a private variable.
For example, in a MV-something pattern, your model would not have much logic. But you can mix and match as needed.
If you were to use a field like you suggested in place of a property, you can't for example define an interface to describe your class correctly, since interfaces cannot contain data fields.
A property is like a contract, and you can change the implemenation of a property without affecting the clients using your classes and properties. You may not have any logic today, but as business requirements change and if you want to introduce any code, properties are your safest bet. The following 2 links are excellent c# video tutorials. The first one explains the need of properties over just using fields and the second video explains different types of properties. I found them very useful.
Need for the Properties in C#
Poperties in C#, Read Only, Write Only, Read/Write, Auto Implemented
Take a look at the following code and explanation.
The most common implementation for a property is getter or a setter that simply reads and writes to a private field of the same type as a property. An automatic property declaration instructs the compiler to provide this implementation. The compiler automatically generates a private backing field.
Look into the following code:-
public class Stock
{
decimal currentPrice ; // private backing field.
public decimal CurrentPrice
{
get { return currentPrice ; }
set { currentPrice = value ; }
}
}
The same code can be rewritten as :-
public class Stock
{
public decimal CurrentPrice { get ; set ; } // The compiler will auto generate a backing field.
}
SOURCE:- C# in a Nutshell

How to determine the attached type from within a custom attribute?

I have a custom attribute which can be assigned to a class, [FooAttribute]. What I would like to do, from within the attribute, is determine which type has actually used me. e.g. If I have:
[FooAttribute]
public class Bar
{
}
In the code for FooAttribute, how can I determine it was Bar class that added me? I'm not specifically looking for the Bar type, I just want to set a friendly name using reflection. e.g.
[FooAttribute(Name="MyFriendlyNameForThisClass")]
public class Bar
{
}
public class FooAttribute()
{
public FooAttribute()
{
// How do I get the target types name? (as a default)
}
}
First off, you might consider the existing [DisplayName] for keeping friendly names. As has already been covered, you simply can't get this information inside the attribute. You can look up the attribute from Bar, but in general, the only way to do it from the attribute would be to pass the type into the attribute - i.e.
[Foo("Some name", typeof(Bar)]
What exactly is it you want to do? There may be other options...
Note that for i18n, resx, etc; you can subclass DisplayNameAttribute and provide lookup from keys by overriding the DisplayName getter.
To elaborat. A attribute, built in or custom, is just meta data for a class, or class member, and the attribute itself nas no notation that it's being associated with something.
The type knows of it's own metadata
The meta data (in this case, the attribute) does not know to whom it belongs
From your sentence "I just want to set a friendly name using reflection" I think you want to set the "MyFriendlyNameForThisClass" name to the attribute at runtime. if so, I don't think that's possible. Please see this thread.
It is clumsy but you could iterate over all classes in the assembly, testing each for the custom attribute that "is" this instance.

Categories