Using Code Contracts to ensure collection remains unchanged - c#

I'm trying to implement the post-condition of a method. I want to guarantee that it doesn't change a particular part of the internal state (I fixed a bug, as it used to do so. For refression purposed, I'm adding the post-condition in code). My best attempt was as follows:
Contract.Ensures(PropertyA.Collection.Count == Contract.OldValue(PropertyA.Collection).Count);
Contract.Ensures(Contract.ForAll(0, PropertyA.Collection.Count, index => this.PropertyA.Collection[index].Equals(Contract.OldValue(this.PropertyA.Collection)[index])));
The problem with this code is that Contract.OldValue(PropertyA.Collection) caused a null reference exception in the second line. In the manual of Code Contracts in section 11.8 (http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf) is stated that this particular Contract.ForAll ought to work with Contract.OldValue, but another overload doesn't.
Is there another way how I can perform the check that the items in PropertyA.Collection haven't changed in value, nor have been reordered in some way?

It is unclear from your question, but I expect that PropertyA.Collection and PropertyB.Collection are reference types.
One gotcha with Contracts.OldValue() and reference types is, that Contracts.OldValue() doesn't save the old object pointed at, but rather the pointer itself.
For this reason, your first contract will always be true, since you effectively compare the value to itself.
The proper way to write it would be
Contract.Ensures(PropertyA.Collection.Count == Contract.OldValue(PropertyA.Collection.Count));
I'm not sure why your second contract fails.
Normally when trying to compare a collection before and after a method call, you need to save the collection as an enumerable:
Contract.OldValue(PropertyA.Collection.ToList())
// or
Contract.OldValue(PropertyA.Collection.ToArray())
This will evaluate the expression and save the reverence to the list/array, which can then be indexed.

Sorry to answer so late, but there are not too much activity in code contracts.
I think there are two sides of the problem:
1) To ensure the condition, as you ask, I think that can be done using a [Pure] function to do it, and calling this function in the Contract.Ensures
2) Unfortunately it only solves the problem locally. Note this situation:
1- Call a function which ensures a condition on de collection
2- Call a function which ensures no change in the collection
3- Call a function which has as precondition the condition ensured in (1)
The [Pure] function in (2) to ensure no change is done in the collection does not allow CodeContracts to infer that the postcondition in (1) ensures the precondition in (3).
I think that CodeContracts should offer a functionality to ensure no change in an object, but taking the object as the "deep object"; something that lets you write something like
proposal code
Contract.Ensures(PureArgument(PropertyA.Collection))
As the functionality PureArgument should be part of CodeContracts, it could be an attribute:
proposal code
[PureArgument(PropertyA.Collection)]
Note that CodeContracts could check that the PureArgument property is fulfilled, as it can do a deep compare; really complex and expensive to check (it needs a deep copy), but it can be done. But the checking won't be the question, but to check the code to ensure that the parameter is not deep changed, which is not always possible.
Anyway, I'm sure that a feature like that will be great, even without checking it fullfils the assertion, and without checking the code to ensure the parameter is not changed (which is more interesting than checking the assertion is fullfiled, but impossible to cover at all).
Turning back to the question, a solution to ensure that a collection doesn't change could be to use new ReadOnlyCollection(PropertyA.Collection) as parameter, instead of using PropertyA, but it is a change in the code.

Related

Create type by runtime type info using Activator<T>.CreateInstance()

Intro
To create instances on the fly via reflection, we could use:
Activator.CreateInstance
The downside to this is that this returns an object, while I really need the concrete type and since I only know the runtime type I can't cast.
To accomplish this, we can use
Activator.CreateInstance<T>
Which returns a T, but since I don't know T at compile time, this is no use either. At first glance anyway.
Currently I'm using dynamic for this, in a special kind of way:
//I pass the runTimeType as an ITopSecret
// runTimeType implements ITopSecret
dynamic concreteTypeInstance = Activator.CreateInstance(runTimeType);
// Now we just have an empty RunTimeType.
// I can use the passed runTimeType to fill the newly created object
concreteTypeInstance = runTimeType
// Then I call ApplyCurrentValues.
// Can't pass runTimeType, because it's ITopSecret and
// EF doesn't figure out the actual runtime type.
context.ApplyCurrentValues(concreteTypeInstance)
Before this line some sanity checks are performed. For example I know the runtime type is always a certain ITopSecret at this point, otherwise the statement can't get hit.
So presumably this is reasonably safe. It does exactly what I want, with 1 line of code, which seems great.
However I'm not sure this is the intended way of using dynamic and if I'm setting the door open for nasty stuff.
Why do I want this
Currently we have 1000s of lines of boilerplate code in many Update methodes across various services. This is handcrafted, thus error-prone, repetetive, violates DRY and makes it harder for new people.
Furthermore this makes the methods unclear by losing focus on business logic and, frankly, is just plain ugly. All the usual suspects ;)
So I'm writing some abstract/generic code to factor out all that repetitive stuff. Which is a very nice and cool bit of software to write, but leaves me with (mostly) runtime info.
Under the surface these methods all use Entity Framework and its ApplyCurrentValues method. This method requires a concrete, instantianted, type and hence my questions.
Hope this is clear enough :)
Questions
Is this an OK way to use dynamic, considering I perform do some sanity checks before actually using it?
I feel that there's a way using reflection to accomplish this. That might be worse in terms of performance, but I'm very curious if this can be done.
Is it possible to create the generic Activator.CreateInstance<T> using reflection?
Are either possibilities bad and should I take a different approach entirely?
However not knowing the concrete types at run-time, but needing them anyway is not something I can move away from.

Using FakeItEasy, is it possible to create a dummy object of a type that takes generic type parameters

I have the following test:
[Fact]
public void StartProgram_CallsZoneProgramStart()
{
var zone = A.Fake<Zone>();
zone.StartProgram();
A.CallTo(() => zone.ZoneProgram.Start(null, A.Dummy<ActionBlock<InterruptInfo>>())).MustHaveHappened(Repeated.Exactly.Once);
}
It's creating a dummy of type ActionBlock<InterruptInfo> which is being passed into the MustHaveHappened call. zone.StartProgram definitely calles the zone.ZoneProgram.Start method, but this call is not seen by FakeItEasy. It returns the following error message:
Assertion failed for the following call:
ZoneLighting.ZoneProgramNS.ZoneProgram.Start(<NULL>, ActionBlock\`1 Id=1)
Expected to find it exactly once but found it #0 times among the calls:
1: ZoneLighting.ZoneProgramNS.ZoneProgram.Start(inputStartingValues: Faked ZoneLighting.ZoneProgramNS.InputStartingValues, interruptQueue: ActionBlock`1 Id=2)
2: ZoneLighting.ZoneProgramNS.ZoneProgram.Start(inputStartingValues: <NULL>, interruptQueue: ActionBlock`1 Id=2)
As can be seen from the error message, the ID on the ActionBlocks being compared are different (1 and 2), which is why it's not able to see that the call is made. My question is, why is the ID of the dummied ActionBlock = 1? I thought being a dummy object, it shouldn't have any concrete details in it like ID etc. Is this because generic types cannot be dummied?
I saw something similar here: https://github.com/FakeItEasy/FakeItEasy/issues/402
But I wasn't able to figure out if that's talking about the same thing or not. Any help would be greatly appreciated.
I am not familiar with ActionBlocks, so am not sure where they get their Id values from, but I think I can shed some light on what's going on in your test.
First, I think you're confused about what a Dummy is. If so, don't feel bad. They can be a little confusing. From the Dummy documentation, a Dummy is
Dummy is an object that FakeItEasy can provide when an object of a certain type is required, but the actual behavior of the object is not important.
They are mostly used by FakeItEasy itself when it needs to create an object to feed to class constructors (we'll see more about that later), or when it needs to return a non-fakeable object from a method or property. It's rare for end users to have to create them.
A Dummy is an actual object (it has to be—otherwise, how could we do anything with it?). It has to have whatever concrete details in it that its type has (in this case, ActionBlock<InterruptInfo>). There are no restrictions against Dummying generic types.
Looking at the docs for how a Dummy is made, we can see that since ActionBlock<InterruptInfo> probably doesn't have a custom IDummyDefinition available (do you have one?), and it's not a Task, and it's not fakeable (because the class is sealed), then the Dummy is made by invoking one of the ActionBlock constructors, with Dummies being made to satifsy each of the arguments.
I guess that ActionBlocks have IDs. How they're assigned, I have no idea, but if they're a good ID, then it looks like we have two different ActionBlock<InterruptInfo>s: one provided in zone.StartProgram, and the Dummy made in the test.
The ActionBlocks documentation suggests that it doesn't override Equals, so a reference comparison will be performed, and the two ActionBlocks (the Dummy and the one used in the production code) don't match. This is why FakeItEasy doesn't recognize the call.
If you were just trying to see if any call to zone.ZoneProgram.Start was made with the first argument null and the second argument some ActionBlock, I think you might've meant to use:
A.CallTo(() => zone.ZoneProgram.Start(null, A<ActionBlock<InterruptInfo>>.Ignored))
.MustHaveHappened(Repeated.Exactly.Once);
(Ignored can also be shortened to _. Read more about ignoring argument values if you're so inclined.)
That may get you past your immediate problem, although I have concerns about two things:
It looks like zone.ZoneProgram.Start is being called twice, not "Exactly.Once", but I'm sure you'll be able to deal with this, and
In general, faking the object under test is considered to be an anti-pattern. Typically one supplies fake dependencies to the production code under test. I'm not saying it won't work, but sometimes it can lead to confusion. Still, it may be a problem for another day, after the current question has been resolved.
I hope that helps a little.
Oh, and you asked about Issue 402. That issue is about giving users more power when defining customization classes that will control how dummies are created. Unless you've made a class extending IDummyDefinition or DummyDefinition, it's probably not relevant at this point.

Can I tag a C# function as "this function does not enumerate the IEnumerable parameter"?

Multiple enumeration of the same enumerable is something that has been a performance problem for us, so we try to stomp those warnings in the code. But there is a generic extension function that we have for throwing null parameter exceptions that generates a lot of these warnings. Its signature looks like this:
public static void VerifyArgumentIsNotNull<T>(this T value, string valueName) where T : class
All it does is check for null and throw a nicely formatted and localized (for whichever human language is in play at the time) exception.
When this function is used on an IEnumerable parameter, it makes the code analysis warn about a possible multiple iteration of the IEnumerable because the analyzer has no idea what that function does.
I would like to put some tag on this function that says, "Yes, this takes the enumerable as an input, but it does not iterate it and therefore should not be counted as a possible iteration by callers." Is there any such tag? I've searched the Internet to no avail.
Yes, what you're asking is very much possible, but requires a little work. ReSharper uses Code Annotations to add hints to its analysis engine and make more sense of the code it has to work with. I recently recorded a webinar with JetBrains called ReSharper Secrets, where I go into much greater detail about what Annotations are and how to use them. You should watch it!
There's an annotation attribute, [NoEnumeration] that does exactly what you ask - specifies that the given IEnumerable argument is not enumerated, however it's not included in the default Code Annotation Attributes, however it is defined in the JetBrains.Annotations.dll assembly.
So after this introduction, here's what you need to do:
(if you haven't already,) go to ReSharper Options, then Code Inspection → Code Annotations, and press the Copy default implementation to clipboard button
Create a file in any of your (shared) projects called Annotations.cs (or any other name)
Paste the code from the clipboard, completely replacing anything that was previously in Annotations.cs
Add the following definition at the end of the file:
Code:
/// <summary>
/// Indicates that IEnumarable, passed as parameter, is not enumerated.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class NoEnumerationAttribute : Attribute
{
}
After you done this, all that's left to do is place the [NoEnumeration] attribute on the value argument, like this:
public static void VerifyArgumentIsNotNull<T>([NoEnumeration] this T value, string valueName) where T : class
{
....
}
And that's it! The warning will disappear!
Bonus:
There are 3 additional attributes you can use to decorate this method to make it even more useful: [NotNull], [ContractAnnotation] and [InvokerParameterName]. I recently describe what they do (and a short demo) in this issue for a similar API called LiteGuard.
Annotations are fun :)
Since VerifyArgumentIsNotNull is generic, but does nothing type specific, it can take an object:
public static void VerifyArgumentIsNotNull(this object #object, string argumentName) { ... }
Resharper (9.11.) assumes that the called method does not cast #object back to an IEnumerable, and thus there is no warning.
Note the lack of the class constraint means the compiler may not warn if you accidentally pass a value type to VerifyArgumentIsNotNull, but Resharper will warn that a value type can never be null.
This approach has the additional advantage of saving the JIT from creating an instance (closed generic) method for every type that VerifyArgumentIsNotNull is called with; a micro-optimization to be sure, but a rare example where a generic may not be preferable to an old-school object.
One possible drawback to the above: I have seen similar implementations where VerifyArgumentIsNotNull returns "value". In this case a return value of type T is needed to avoid an explicit cast. (IMO this syntax is ugly. So it is not a drawback for me.)
Two other editorial comments:
1. A method name I have seen: ThrowIfNull is more concise, and "Throw" is more explicit than "Verify"
2. I no longer use methods for this, because without an annotation on VerifyArgumentIsNotNull Resharper must assume the argument could still be null. I find it much simpler to let R#, insert a 1-line if + throw when I add the NotNullAttribute.
This approach does not work for the broader case where you want to ensure that a method is called with an enumerable. In this case Igal Tabachnik's additions to Annotations are great.
Assuming you are using Visual Studio 2013/2012 (I'm only aware of this feature in 2013 though) in the code analysis window you should be able to right click the message navigate to Suppress Message > In Source File or In Suppression File
Alternatively you can achieve the same effect by clicking the action drop down of the message in the Code Analysis window.

Snappy names for a ReferenceType value and a ValueType value

I have 2 classes. One handles a ReferenceType value, another does the same on a ValueType value. This is the only difference, but it is important. I am struggling to find a decent name for each class:
ReferenceTypeValueHandler and ValueTypeValueHandler?
Neah, ValueTypeValue sounds confusing.
ClassValueHandler and StructValueHandler?
I shouldn't use "Class" in a name of a class, should I?
NullableValueHandler and NonNullableValueHandler?
"Nullable" is already used for nullable value types (Nullable<>)
HeapValueHandler and StackValueHandler?
That's dumb. Exploiting the fact that reference type values are stored in the heap and value type values are in the stack, who cares? Also "Stack" is confusing implying it has something to do with a stack.
Any more ideas?
Update:
Some people suggest I should explain the purpose of the class. Well, although I don't think it's important, here it is: I am working on a XML to entity deserializer. I use XmlReader to take advantage of the streamline reading rather then working with DOM. As I read XML I build entities. Some entities are just wrappers for some other ones. These wrappers can take either a single entity or a collection (enumerable) of entities. Speaking of those which take a single entity, this entity has to be provided and it has to be provided exactly one time. If XML doesn't have it, it's a problem. If XML has more than 1 it's a problem too. So for keeping and ensuring that the entity is provided exactly one time I have a class ValueKeeper<TValue>. It has 2 methods TakeValue(TValue value) and TValue ClaimValue(). The TakeValue methods takes the value and checks if there is already a value provided before, if so it throws the exception with appropriate details. The ClaimValue method is called once the reading of the wrapper XML is finished and the wrapper entity has to be created over the scraped value, this method checks whether there is a value that was received via the TakeValue method, if so
it just returns that value, if no, then it throws the exception. Now, the problem is that for reference type values I am using comparison to NULL in order to see if the value was provided. In order to make such comparison possible there must be a generic constraint on the TValue type parameter: where TValue: class. Having this constraint in place I cannot use this class for value type values. So I need another class that does the same, but operates on values where TValue: struct using a Nullable<TValue> field to keep either provided or not-yet provided value. Now, with 2 classes I cannot go along just with ValueKeeper, I need one name for the reference type and another for the value type value. Here is where the question comes up. I need a way to express this subtle difference. But again, it's not important what the class does, what's important is to find appropriate way to put this difference clear.
I wouldn't agree that the rest of the class name is not important. You want to make your code speak for itself and to make it easy for the reader to understand the concepts you had in mind when designing the classes/structs. The class names you suggest would give me no idea of what the class is actually doing. I suggest to search for more concrete names: How is the value being handled? What value?
How do struct and class values differ from each other apart from that one is a class and the other one a struct? There must be some more difference because otherwise it wouldn't make sense to have the same thing as a struct and as a class (DRY).
If it's a very abstract operation you perform, try to search for the pattern, or a general name for a concept. To keep the value and make sure it was provided sounds a bit like a caching mechanism?
Secondly, your facing a semantic issue here: what is the term which subsumes 'values' of value types and 'values' of reference types. We could simply ask the inheritance chain of the .NET framework here and call it both an object.
So, in this case, something like CacheForValueTypeObjects and CacheForReferenceTypeObjects could work. I don't know whether cache expresses the purpose well, but if not, I would try to search for a term which best describes the 'final' purpose of the class, the reason why its there.
I bet you didn't think 'Well, what I really need now is a ValueTypeValueHandler!'. There was something more to it. ;) I like this kind of questions, thanks!

Why should I avoid using Properties in C#?

In his excellent book, CLR Via C#, Jeffrey Richter said that he doesn't like properties, and recommends not to use them. He gave some reason, but I don't really understand. Can anyone explain to me why I should or should not use properties?
In C# 3.0, with automatic properties, does this change?
As a reference, I added Jeffrey Richter's opinions:
• A property may be read-only or write-only; field access is always readable and writable.
If you define a property, it is best to offer both get and set accessor methods.
• A property method may throw an exception; field access never throws an exception.
• A property cannot be passed as an out or ref parameter to a method; a field can. For
example, the following code will not compile:
using System;
public sealed class SomeType
{
private static String Name
{
get { return null; }
set {}
}
static void MethodWithOutParam(out String n) { n = null; }
public static void Main()
{
// For the line of code below, the C# compiler emits the following:
// error CS0206: A property or indexer may not
// be passed as an out or ref parameter
MethodWithOutParam(out Name);
}
}
• A property method can take a long time to execute; field access always completes immediately.
A common reason to use properties is to perform thread synchronization, which
can stop the thread forever, and therefore, a property should not be used if thread synchronization
is required. In that situation, a method is preferred. Also, if your class can be
accessed remotely (for example, your class is derived from System.MashalByRefObject),
calling the property method will be very slow, and therefore, a method is preferred to a
property. In my opinion, classes derived from MarshalByRefObject should never use
properties.
• If called multiple times in a row, a property method may return a different value each
time; a field returns the same value each time. The System.DateTime class has a readonly
Now property that returns the current date and time. Each time you query this
property, it will return a different value. This is a mistake, and Microsoft wishes that they
could fix the class by making Now a method instead of a property.
• A property method may cause observable side effects; field access never does. In other
words, a user of a type should be able to set various properties defined by a type in any
order he or she chooses without noticing any different behavior in the type.
• A property method may require additional memory or return a reference to something
that is not actually part of the object's state, so modifying the returned object has no
effect on the original object; querying a field always returns a reference to an object that
is guaranteed to be part of the original object's state. Working with a property that
returns a copy can be very confusing to developers, and this characteristic is frequently
not documented.
Jeff's reason for disliking properties is because they look like fields - so developers who don't understand the difference will treat them as if they're fields, assuming that they'll be cheap to execute etc.
Personally I disagree with him on this particular point - I find properties make the client code much simpler to read than the equivalent method calls. I agree that developers need to know that properties are basically methods in disguise - but I think that educating developers about that is better than making code harder to read using methods. (In particular, having seen Java code with several getters and setters being called in the same statement, I know that the equivalent C# code would be a lot simpler to read. The Law of Demeter is all very well in theory, but sometimes foo.Name.Length really is the right thing to use...)
(And no, automatically implemented properties don't really change any of this.)
This is slightly like the arguments against using extension methods - I can understand the reasoning, but the practical benefit (when used sparingly) outweighs the downside in my view.
Well, lets take his arguments one by one:
A property may be read-only or
write-only; field access is always
readable and writable.
This is a win for properties, since you have more fine-grained control of access.
A property method may throw an
exception; field access never throws
an exception.
While this is mostly true, you can very well call a method on a not initialized object field, and have an exception thrown.
• A property cannot be passed as an
out or ref parameter to a method; a
field can.
Fair.
• A property method can take a long
time to execute; field access always
completes immediately.
It can also take very little time.
• If called multiple times in a row, a
property method may return a different
value each time; a field returns the
same value each time.
Not true. How do you know the field's value has not changed (possibly by another thread)?
The System.DateTime class has a
readonly Now property that returns the
current date and time. Each time you
query this property, it will return a
different value. This is a mistake,
and Microsoft wishes that they could
fix the class by making Now a method
instead of a property.
If it is a mistake it's a minor one.
• A property method may cause
observable side effects; field access
never does. In other words, a user of
a type should be able to set various
properties defined by a type in any
order he or she chooses without
noticing any different behavior in the
type.
Fair.
• A property method may require
additional memory or return a
reference to something that is not
actually part of the object's state,
so modifying the returned object has
no effect on the original object;
querying a field always returns a
reference to an object that is
guaranteed to be part of the original
object's state. Working with a
property that returns a copy can be
very confusing to developers, and this
characteristic is frequently not
documented.
Most of the protestations could be said for Java's getters and setters too --and we had them for quite a while without such problems in practice.
I think most of the problems could be solved by better syntax highlighting (i.e differentiating properties from fields) so the programmer knows what to expect.
I haven't read the book, and you haven't quoted the part of it you don't understand, so I'll have to guess.
Some people dislike properties because they can make your code do surprising things.
If I type Foo.Bar, people reading it will normally expect that this is simply accessing a member field of the Foo class. It's a cheap, almost free, operation, and it's deterministic. I can call it over and over, and get the same result every time.
Instead, with properties, it might actually be a function call. It might be an infinite loop. It might open a database connection. It might return different values every time I access it.
It is a similar argument to why Linus hates C++. Your code can act surprising to the reader. He hates operator overloading: a + b doesn't necessarily mean simple addition. It may mean some hugely complicated operation, just like C# properties. It may have side effects. It may do anything.
Honestly, I think this is a weak argument. Both languages are full of things like this. (Should we avoid operator overloading in C# as well? After all, the same argument can be used there)
Properties allow abstraction. We can pretend that something is a regular field, and use it as if it was one, and not have to worry about what goes on behind the scenes.
That's usually considered a good thing, but it obviously relies on the programmer writing meaningful abstractions. Your properties should behave like fields. They shouldn't have side effects, they shouldn't perform expensive or unsafe operations. We want to be able to think of them as fields.
However, I have another reason to find them less than perfect. They can not be passed by reference to other functions.
Fields can be passed as ref, allowing a called function to access it directly. Functions can be passed as delegates, allowing a called function to access it directly.
Properties... can't.
That sucks.
But that doesn't mean properties are evil or shouldn't be used. For many purposes, they're great.
Back in 2009, this advice merely seemed like bellyaching of the Who Moved My Cheese variety. Today, it's almost laughably obsolete.
One very important point that many answers seem to tiptoe around but don't quite address head on is that these purported "dangers" of properties are an intentional part of the framework design!
Yes, properties can:
Specify different access modifiers for the getter and setter. This is an advantage over fields. A common pattern is to have a public getter and a protected or internal setter, a very useful inheritance technique which isn't achievable by fields alone.
Throw an exception. To date, this remains one of the most effective methods of validation, especially when working with UI frameworks that involve data-binding concepts. It's much more difficult to ensure that an object remains in a valid state when working with fields.
Take a long time to execute. The valid comparison here is with methods, which take equally long - not fields. No basis is given for the statement "a method is preferred" other than one author's personal preference.
Return different values from its getter on subsequent executions. This almost seems like a joke in such close proximity to the point extolling the virtues of ref/out parameters with fields, whose value of a field after a ref/out call is pretty much guaranteed to be different from its previous value, and unpredictably so.
If we're talking about the specific (and practically academic) case of single-threaded access with no afferent couplings, it's fairly well understood that it's just bad property design to have visible-state-changing side-effects, and maybe my memory is fading, but I just can't seem to recall any examples of folks using DateTime.Now and expecting the same value to come out every time. At least not any instances where they wouldn't have screwed it up just as badly with a hypothetical DateTime.Now().
Cause observable side effects - which is of course precisely the reason properties were invented as a language feature in the first place. Microsoft's own Property Design guidelines indicate that setter order shouldn't matter, as to do otherwise would imply temporal coupling. Certainly, you can't achieve temporal coupling with fields alone, but that's only because you can't cause any meaningful behaviour at all to happen with fields alone, until some method is executed.
Property accessors can actually help prevent certain types of temporal coupling by forcing the object into a valid state before any action is taken - for example, if a class has a StartDate and an EndDate, then setting the EndDate before the StartDate could force the StartDate back as well. This is true even in multi-threaded or asynchronous environments, including the obvious example of an event-driven user interface.
Other things that properties can do which fields can't include:
Lazy loading, one of the most effective ways of preventing initialization-order errors.
Change Notifications, which are pretty much the entire basis for the MVVM architecture.
Inheritance, for example defining an abstract Type or Name so derived classes can provide interesting but nevertheless constant metadata about themselves.
Interception, thanks to the above.
Indexers, which everyone who has ever had to work with COM interop and the inevitable spew of Item(i) calls will recognize as a wonderful thing.
Work with PropertyDescriptor which is essential for creating designers and for XAML frameworks in general.
Richter is clearly a prolific author and knows a lot about the CLR and C#, but I have to say, it seems like when he originally wrote this advice (I'm not sure if it's in his more recent revisions - I sincerely hope not) that he just didn't want to let go of old habits and was having trouble accepting the conventions of C# (vs. C++, for example).
What I mean by this is, his "properties considered harmful" argument essentially boils down to a single statement: Properties look like fields, but they might not act like fields. And the problem with the statement is, it isn't true, or at best it's highly misleading. Properties don't look like fields - at least, they aren't supposed to look like fields.
There are two very strong coding conventions in C# with similar conventions shared by other CLR languages, and FXCop will scream at you if you don't follow them:
Fields should always be private, never public.
Fields should be declared in camelCase. Properties are PascalCase.
Thus, there is no ambiguity over whether Foo.Bar = 42 is a property accessor or a field accessor. It's a property accessor and should be treated like any other method - it might be slow, it might throw an exception, etc. That's the nature of Abstraction - it's entirely up to the discretion of the declaring class how to react. Class designers should apply the principle of least surprise but callers should not assume anything about a property except that it does what it says on the tin. That's on purpose.
The alternative to properties is getter/setter methods everywhere. That's the Java approach, and it's been controversial since the beginning. It's fine if that's your bag, but it's just not how we roll in the .NET camp. We try, at least within the confines of a statically-typed system, to avoid what Fowler calls Syntactic Noise. We don't want extra parentheses, extra get/set warts, or extra method signatures - not if we can avoid them without any loss of clarity.
Say whatever you like, but foo.Bar.Baz = quux.Answers[42] is always going to be a lot easier to read than foo.getBar().setBaz(quux.getAnswers().getItem(42)). And when you're reading thousands of lines of this a day, it makes a difference.
(And if your natural response to the above paragraph is to say, "sure it's hard to read, but it would be easier if you split it up in multiple lines", then I'm sorry to say that you have completely missed the point.)
I don't see any reasons why you shouldn't use Properties in general.
Automatic properties in C# 3+ only simplify syntax a bit (a la syntatic sugar).
It's just one person's opinion. I've read quite a few c# books and I've yet to see anyone else saying "don't use properties".
I personally think properties are one of the best things about c#. They allow you to expose state via whatever mechanism you like. You can lazily instantiate the first time something is used and you can do validation on setting a value etc. When using and writing them, I just think of properties as setters and getters which a much nicer syntax.
As for the caveats with properties, there are a couple. One is probably a misuse of properties, the other can be subtle.
Firstly, properties are types of methods. It can be surprising if you place complicated logic in a property because most users of a class will expect the property to be fairly lightweight.
E.g.
public class WorkerUsingMethod
{
// Explicitly obvious that calculation is being done here
public int CalculateResult()
{
return ExpensiveLongRunningCalculation();
}
}
public class WorkerUsingProperty
{
// Not at all obvious. Looks like it may just be returning a cached result.
public int Result
{
get { return ExpensiveLongRunningCalculation(); }
}
}
I find that using methods for these cases helps to make a distinction.
Secondly, and more importantly, properties can have side-effects if you evaluate them while debugging.
Say you have some property like this:
public int Result
{
get
{
m_numberQueries++;
return m_result;
}
}
Now suppose you have an exception that occurs when too many queries are made. Guess what happens when you start debugging and rollover the property in the debugger? Bad things. Avoid doing this! Looking at the property changes the state of the program.
These are the only caveats I have. I think the benefits of properties far outweigh the problems.
That reason must have been given within a very specific context. It's usually the other way round - it is recomended to use properties as they give you a level of abstraction enabling you to change behaviour of a class without affecting its clients...
I can't help picking on the details of Jeffrey Richter's opinions:
A property may be read-only or write-only; field access is always readable and writable.
Wrong: Fields can marked read-only so only the object's constructor can write to them.
A property method may throw an exception; field access never throws an exception.
Wrong: The implementation of a class can change the access modifier of a field from public to private. Attempts to read private fields at runtime will always result in an exception.
I don't agree with Jeffrey Richter, but I can guess why he doesn't like properties (I haven't read his book).
Even though, properties are just like methods (implementation-wise), as a user of a class, I expect that its properties behave "more or less" like a public field, e.g:
there's no time-consuming operation going on inside the property getter/setter
the property getter has no side effects (calling it multiple times, does not change the result)
Unfortunately, I have seen properties which did not behave that way. But the problem are not the properties themselves, but the people who implemented them. So it just requires some education.
The argument assumes that properties are bad because they look like fields, but can do surprising actions. This assumption is invalidated by .NET programmers' expectactions:
Properties don't look like fields. Fields look like properties.
• A property method may throw an exception; field access never throws an exception.
So, a field is like a property that is guaranteed to never throw an exception.
• A property cannot be passed as an out or ref parameter to a method; a field can.
So, a field is like a property, but it has additional capabilities: passing to a ref/out accepting methods.
• A property method can take a long time to execute; field access always completes immediately. [...]
So, a field is like a fast property.
• If called multiple times in a row, a property method may return a different value each time; a field returns the same value each time. The System.DateTime class has a readonly Now property that returns the current date and time.
So, a field is like a property that is guaranteed to return the same value unless the field was set to a different value.
• A property method may cause observable side effects; field access never does.
Again, a field is a property that is guaranteed to not do that.
• A property method may require additional memory or return a reference to something that is not actually part of the object's state, so modifying the returned object has no effect on the original object; querying a field always returns a reference to an object that is guaranteed to be part of the original object's state. Working with a property that returns a copy can be very confusing to developers, and this characteristic is frequently not documented.
This one may be surprising, but not because it's a property that does this. Rather, it's that barely anyone returns mutable copies in properties, so that 0.1% case is surprising.
There is a time when I consider not using properties, and that is in writing .Net Compact Framework code. The CF JIT compiler does not perform the same optimisation as the desktop JIT compiler and does not optimise simple property accessors, so in this case adding a simple property causes a small amount of code bloat over using a public field. Usually this wouldn't be an issue, but almost always in the Compact Framework world you are up against tight memory constraints, so even tiny savings like this do count.
You shouldn't avoid using them but you should use them with qualification and care, for the reasons given by other contributors.
I once saw a property called something like Customers that internally opened an out-of-process call to a database and read the customer list. The client code had a 'for (int i to Customers.Count)' which was causing a separate call to the database on each iteration and for the access of the selected Customer. That's an egregious example that demonstrates the principle of keeping the property very light - rarely more than a internal field access.
One argument FOR using properties is that they allow you to validate the value being set. Another is that the value of of the property may be a derived value, not a single field, like TotalValue = amount * quantity.
Personally I only use properties when creating simple get / set methods. I stray away from it when coming to complicated data structures.
I haven't read his book but I agree with him.
It's quite a contradiction on the usual paradigm.
They look like a field but had many sideeffects. Exceptions, performance, sideeffects, read/write access difference, etc.
If you care about readability and reliability i think you'd care about this as well.
In my experience i never gained anything from properties and only felt like using them when i was lazy.
But many times i encountered people using properties as if they were fields inadvertently creating all sort of issues.
Ive worked professionally on many languages for quite a time and never needed them, not even once.
Of course other people might find them useful and that's fine too.
Depends on your user case and what you value.
I personally believe they are just 'features ' that you can choose to use or not.
Invoking methods instead of properties greatly reduces the readability of the invoking code. In J#, for example, using ADO.NET was a nightmare because Java doesn't support properties and indexers (which are essentially properties with arguments). The resulting code was extremely ugly, with empty parentheses method calls all over the place.
The support for properties and indexers is one of the basic advantages of C# over Java.

Categories