Related
So, I've just discovered the wonderful DebuggerDisplay attribute, and have started using it in my code. I've noticed something really quirky about it, though, or perhaps the issue is actually with KeyedCollection.
Without a DebuggerDisplay attribute, I get "Count = x" as the primary display for a KeyedCollection, and that expands to show the elements of the collection. Adding the attribute, however, I get my custom text, as expected, but it now expands to show the various values and properties that I've added to the object itself. That's great, and makes far more sense to me than the collection-->Raw View style that shows up by default. Now, though, the Results View isn't populated by default, it instead has the customary "Expanding the Results View will enumerate the IEnumerable".
How do I get rid of that behaviour? I know the results are safe to enumerate, and would like them to be enumerated automatically. For bonus points, can I have it auto-expand the selection as well?
As I said in my comments, the closest you can be to what you want is by using the DebuggerTypeProxyAttribute. Unfortunately it's a sealed type so you might not be able to make it easy to reuse.
This is more of an architecture / design question.
I have run into a few projects in the past written in WPF/Windows Forms, etc. that have complex screens with a lot of fields and these fields are connected to each other (their values depend on each other with some logic involved).
These projects I have taken on after they were implemented, and I found a lot of events / data bind hell - what I mean by this is that because all these fields are depending on others they have implemented INotifyPropertyChanged and other fields are being modified as a result. This causes the same fields being updated 5-6 times when the screen loads and the order in which fields are populated causes horrible bugs. (For example, Date was set before Job Type, instead of after Job Type, so I end up with a different Job Fee.)
To make matters worse, some hacks are implemented on UI events (for example, DropDown changed to update field X) while others are in the domain model that the UI binds to.
Basically, it's a huge mess, and I just want to know what the best way to implement something like this is if I was to start from scratch. Or is it a good idea to avoid such a complex screen in the first place?
I would try to keep the business logic out of the property setters as much as possible.
First of all, if several properties are needed for one calculation, I'd write one method that does the calculation, and call that method when appropriate. E.g. if all different combinations of property values make sense, one could just call the method in the setters of each property, making sure that the same code runs any time one of the properties is changed. If you only can evaluate special combinations of property values, you could either implement a command and let the user decide when to calculate the resulting changes, or you could provide feedback through validation, and only evaluate the property changes if the combination is valid. If there are several interdependent properties, I often use a "ChangeInitiator" variable to indicate what property has changed, so that it is clear in the calculation method which property is responsible for the change and which others should change as a result. Basically, this is the same as doing one part of the calculation in each property setter, but I find that it helps me to keep an overview of things if the different parts of the relationship are all in one method.
In a program I wrote once, I had some calculations running on a background thread periodically, so I would just set a flag whenever a piece of data changed that required a new calculation, and do all the updates based on a timer every second or so... that could also help you get the logic more straight, and it avoids to have the calculation run several times for one set of related changes.
With regard to change notification, I'd really try to only use it for UI data binding.
We have fairly complex UIs (including several related fields of different types in, say for example a Row in a DataGrid) and the MVVM pattern has worked pretty well for us. All the properties coming from the Model and exposed to the View that have complex logic related are "wrapped" by an equivalent property in the ViewModel, which has no Backing Field, but rather points directly to the Model:
public class SomeComplexViewModel
{
public SomeModel Model {get;set;}
public string SomeCrazyProperty
{
get
{
return Model.SomeCrazyProperty;
}
{
Model.SomeCrazyProperty = value;
//... Some crazy logic here, potentially modifying some other properties as well.
}
}
}
<TextBox Text="{Binding SomeCrazyProperty}"/>
This removes the "initial value" problem, as the initial value read by the Binding is actually the real value coming from the Model, and thus the logic placed in the Setter is executed only when needed.
Then, for dummy properties (which have no logic behind), we bind directly from the View to the Model:
<TextBox Text="{Binding Model.SomeRegularProperty}"/>
This reduces the bloat in the ViewModel.
With regard to events in the code behind, I totally avoid that. My code behind files are almost always one InitializeComponent() and nothing else.
Only View-Specific logic is placed in the code behind (such as animations stuff, etc), when it cannot be directly done in XAML, or is easier to do in code (which is not the case most of the time).
Edit:
It's important to mention that the winforms binding capabilities are a joke compared to the XAML-based ones. could that be the cause you're seeing those horrible messes in those projects?
Between these two:
With Property:
class WithProperty
{
public string MyString {get; set;}
}
With Field:
class WithField
{
public string MyString;
}
Apparently I'm supposed to pick the first one. Why?
I've heard the argument that the point here is to allow interface changes, but
if I have the second one, and change it to the first one, no other code should
ever have to change. When recompiled everything's just going to point to the
property instead.
Am I missing something important here?
The most important difference is the fact, that if you use a field, and later need to change it to a property (say, to enforce some validation), then all libraries calling your code will need to be recompiled. It's true that you can compile the exact same code if the name stays the same - but the consumers of your code will still need to be recompiled. This is because the IL generated to get the value is different between a field and a property. If it already is a property, you can make a change without forcing consumers of your code to change.
This may or may not be an issue for you. But the property is almost the same amount of code, and is considered best practice. I would always go for the property.
The property can be changed later if you need to add validation or other logic without breaking other assemblies.
Also, the property can be used with databinding.
The important part you are missing is the gravity of this statement:
When recompiled
When your code point to a field and you change it to point to a property of the same name, the C# itself doesn't change, but the resulting IL does - it generates a method call to the getter or setter as appropriate.
Not every app has all of it's pieces contained in a single distributed unit. Many apps rely on interfaces for pluggability/expandability. If you have an app with an interface to a field and you want to change it to a property to take advantage of the power of properties, the app has to be recompiled and redistributed. You might as well just make it a property in the first place.
With a property, you can easily extend it to include new logic.
For example, if you need to add validation logic to the set.
This article goes into several additional reasons why you should prefer properties:
http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx
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.
I have seen the following code:
[DefaultValue(100)]
[Description("Some descriptive field here")]
public int MyProperty{...}
The functionality from the above snippit seems clear enough, I have no idea as to how I can use it to do useful things. Im not even sure as to what name to give it!
Does anyone know where I can find more information/a tutorial on these property attributes?
I would be also interested in any novel / useful tasks this feature can do.
The functionality from the above
snippit seems clear enough,
Maybe not, as many people think that [DefaultValue()] sets the value of the property. Actually, all it does to tell some visual designer (e.g. Visual Studio), what the code is going to set the default value to. That way it knows to bold the value in the Property Window if it's set to something else.
People have already covered the UI aspect - attributes have other uses, though... for example, they are used extensively in most serialization frameworks.
Some attributes are given special treatment by the compiler - for example, [PrincipalPermission(...)] adds declarative security to a method, allowing you to (automatically) check that the user has suitable access.
To add your own special handling, you can use PostSharp; there are many great examples of using PostSharp to do AOP things, like logging - or just code simplification, such as with automatic INotifyPropertyChanged implementation.
They are called Attributes, there is a lot of information in msdn, e.g. http://msdn.microsoft.com/en-us/library/z0w1kczw.aspx
In general they don't "do" anything on their own, they are used by some other code that will use your class. XmlSerialization is a good example: XmlSerializer (provided by Microsoft as part of the framework) can almost any class (there are a number of requirements on the class though) - it uses reflection to see what data is contained in the class. You can use attributes (defined together with XmlSerializer) to change the way XmlSerializer will serialize your class (e.g. tell it to save the data as attribute instead of an element).
The ones in your example is used by the visual designer (i.e. MS Expression Blend and Visual Studio designer) to give hints in the designer UI.
Note that they are metadata and will not affect the property logic. Setting DefaultValue for instance will not set the property to that value by default, you have to do that manually.
If you for some reason want to access these attributes, you would have to use reflection.
See MSDN for more information about designer attributes.
We use it to define which graphical designer should be loaded to configure
an instance of a specific type.
That is to say, we have a kind of workflow designer which loads all possible command
types from an assembly. These command types have properties that need to be configured,
so every command type has the need for a different designer (usercontrol).
For example, consider the following command type (called a composite in our solution)
[CompositeMetaData("Delay","Sets the delay between commands",1)]
[CompositeDesigner(typeof(DelayCompositeDesigner))]
public class DelayComposite : CompositeBase
{
// code here
}
This is information is used in two places
1) When the designer creates a list of commands, it uses the CompositeMetaData
to display more information about the command.
2) When the user adds a command to the designer and the designer creates
an instance of that class, it looks at the CompositeDesigner property,
creates a new instance of the specified type (usercontrol) and adds it
to the visual designer.
Consider the following code, we use to load the commands into our "toolbar":
foreach (Type t in assembly.GetExportedTypes())
{
Console.WriteLine(t.Name);
if (t.Name.EndsWith("Composite"))
{
var attributes = t.GetCustomAttributes(false);
ToolboxListItem item = new ToolboxListItem();
CompositeMetaDataAttribute meta = (CompositeMetaDataAttribute)attributes
.Where(a => a.GetType() == typeof(Vialis.LightLink.Attributes.CompositeMetaDataAttribute)).First();
item.Name = meta.DisplayName;
item.Description = meta.Description;
item.Length = meta.Length;
item.CompositType = t;
this.lstCommands.Items.Add(item);
}
}
As you can see, for every type in the assembly of which the name ends with "Composite",
we get the custom attributes and use that information to populate our ToolboxListItem instance.
As for loading the designer, the attribute is retreived like this:
var designerAttribute = (CompositeDesignerAttribute)item.CompositType.GetCustomAttributes(false)
.Where(a => a.GetType() == typeof(CompositeDesignerAttribute)).FirstOrDefault();
This is just one example of how you might be able to use custom attributes,
I hope this gives you a place to start.
These attributes customize the design time experience.
http://msdn.microsoft.com/en-us/library/a19191fh.aspx