What does the [Intrinsic] attribute in C# do? - c#

A quick Google search for "instrinsic attribute c#" only returns articles about other attributes, such as [Serializable]. Apparently these are called "intrinsic attributes".
However, there is also an attribute in C# that is itself called [Intrinsic] and I'm trying to figure out what exactly it is and how it works. It doesn't exist on the common attributes page of the .NET Documentation, or anywhere else in the documentation as far as I can see.
This attribute is used inside of .NET Core in several places, for example, in the System.Numerics.Vectors folder, such as Vector2_Intrinsics.cs. Code snippet:
[Intrinsic]
public Vector2(float x, float y)
{
X = x;
Y = y;
}

Here's what I've managed to find after a very limited search through dotnet/corefx repository on github.
[Intrinsic] marks methods, properties and fields that can be potentially replaced/optimized by JIT. Source code comments say something similar (IntrinsicAttribute.cs):
Calls to methods or references to fields marked with this attribute may be replaced at some call sites with jit intrinsic expansions. Types marked with this attribute may be specially treated by the runtime/compiler.
Purpose
For core developers, [Intrinsic] serves at least two purposes:
it notifies the developer that the code of the marked field, method or property can be replaced by VM. So, if the code changes, the change should probably be introduced in both places;
it is used as a flag for JIT-optimizer to quickly identify methods that can potentially be optimized.
To give a rough example: JIT-optimizer can replace Enum.HasFlag with a simple bitwise comparison in some cases and not in the others. To do this it needs to identify the method as Enum.HasFlag, check some conditions and replace it with a more optimal implementation. The optimizer can identify the method by name, but, for performance reasons, it's better to filter out methods by a simple flag before performing string comparisons.
Usage
The attribute is only relevant to core developers. You should only use it in an internal class and only in the case when you want to propose very specific JIT-level optimizations for it. [Intrinsic] is pretty much restricted to a small set of widely used .Net classes, that, for some reason, can't be optimized by other means.
from the comments: I'm planning to propose a Color struct for .NET Core which needs to behave similarly to other built-in types for consistency.
You should probably not use [Intrinsic] in your initial proposal. After it passes, you can think about optimization, and if you have a valid scenario when Color will benefit from low level optimizations, you can suggest using [Intrinsic] on some of its methods or properties.
How It Works
Here's how [Intrinsic] is currently used in core:
it is defined as a well-known attribute (wellknownattributes.h):
case WellKnownAttribute::Intrinsic:
return "System.Runtime.CompilerServices.IntrinsicAttribute";
VM parses it and sets the IsJitIntrinsic flag to true for a method (methodtablebuilder.cpp):
if (bmtProp->fIsHardwareIntrinsic || (S_OK == GetCustomAttribute(pMethod->GetMethodSignature().GetToken(),
WellKnownAttribute::Intrinsic,
NULL,
NULL)))
{
pNewMD->SetIsJitIntrinsic();
}
this flag is used to set another flag in method attributes (jitinterface.cpp):
if (pMD->IsJitIntrinsic())
result |= CORINFO_FLG_JIT_INTRINSIC;
this flag is later used to filter out methods which are obviously not intrinsic (importer.cpp):
if ((mflags & (CORINFO_FLG_INTRINSIC | CORINFO_FLG_JIT_INTRINSIC)) != 0)
{
const bool isTail = canTailCall && (tailCall != 0);
call = impIntrinsic(newobjThis, clsHnd, methHnd, sig, mflags, pResolvedToken->token, readonlyCall, isTail,
pConstrainedResolvedToken, callInfo->thisTransform, &intrinsicID, &isSpecialIntrinsic);
impIntrinsic then calls lookupNamedIntrinsic to identify (mostly by name) methods that really (not just potentially) should be optimized;
after all of that importer can perform optimizations based on method. For example, optimization for Enum.HasFlag (importer.cpp):
case NI_System_Enum_HasFlag:
{
GenTree* thisOp = impStackTop(1).val;
GenTree* flagOp = impStackTop(0).val;
GenTree* optTree = gtOptimizeEnumHasFlag(thisOp, flagOp);
if (optTree != nullptr)
{
// Optimization successful. Pop the stack for real.
impPopStack();
impPopStack();
retNode = optTree;
}
else
{
// Retry optimizing this during morph.
isSpecial = true;
}
break;
}
DISCLAIMER: as far as I can tell, the attribute's behaviour is not properly documented anywhere and, thus, is subject for change. The description above is only relevant to code currently in master, this part of core is actively developed and the whole process can be changed in the future.
History
Here's a short timeline of [Intrinsic] based on github repository history:
At some time before 2014 [JitIntrisic] attribute was introduced as a part of System.Numerics with a goal to support new processor instructions (see How does JitIntrinsicAttribute affect code generation?).
On June 6, 2016, Chris McKinsey opened an issue #5626. "Optimize enum1.HasFlag(enum2) into inline bittest without boxing allocations when types are the same". At the time, Enum.HasFlag had a well-known performance issues (see What is it that makes Enum.HasFlag so slow?).
While working on the issue Andy Ayers suggested to introduce a universal mechanism to introduce JIT intrinsics (Issue #13813: Add more flexible method for specifying jit instrinsics)
This led to two pull requests: New jit intrinsic support introduced the general mechanics for [Intrinsic] and JIT: optimize Enum.HasFlag implemented it for Enum.HasFlag. I suggest going through both of them as they are extremely illustrative on the changes that come with [Intrinsic].
Later, during the discussion about moving Vector classes to the CoreLib it was suggested that [JitIntrinsic] isn't used anywhere and should be replaced/removed:
#jkotas: We should not need the JitIntrinsicAttribute. As far as I know, this attribute was future proofing, never used for anything real. We should delete it, and use the IntrinsicAttribute from CoreLib instead.
Promptly, [JitIntrinsic] was removed and replace by [Intrinsic] (Replace JitIntrinsicAttribute with IntrinsicAttribute). That's how this attribute came to be in Vector2.

Explanation:
Special types are indicated to the compiler using the
IntrinsicAttribute custom attribute. If a type is annotated with the
IntrinsicAttribute attribute, the compiler knows not that the
implementation for the given type will be present at runtime.
Methods for types marked as Intrinsic can declare methods to be
extern, in which case the implementation is assumed to be available at
runtime.
Source: MSIL to JavaScript Compiler, section 4.4.1.1
Link: http://tenpow.com/Academics/MSIL2JS/MSIL2JS.pdf
In general, I would suggest not to care about it, nor use it for your own classes.

Related

Reflection to find all methods with a PostSharp aspect applied

I have an OnMethodBoundary aspect I created to keep track of progress events in a template method. One of the things that would be useful to know in terms of the overall progress is the number of progress steps that are required by my process before it finishes, i.e. the number of methods tagged with my [AffectsProgress] attribute.
Rather than hard coding it and having to maintain that as I add and remove methods, I've tried using System.Reflection to determine that with code like the following (there were many variants I tried):
typeof (MyModuleWithProgressSteps)
.GetMethods(/* whatever BindingFlags I need */)
.SelectMany(x => x.CustomAttributes.Where(attribute => attribute.AttributeType == typeof (AffectsProgress)))
However, even though I was able to see other attributes when I removed the Where clause, I was unable to find any PostSharp aspects. My naive guess is that PostSharp aspects that interfere with the call stack upon execution aren't actually traditional method attributes and so the System.Reflection library doesn't see them.
Does anyone know of a way I could get what I'm looking for either with System.Reflection or with PostSharp itself? I came across ReflectionSearch and IAspectRepositoryService which require the Ultimate edition but I'm not sure if those are sufficient or not.
Edit: Resolved by #Daniel Balas. Using that answer and the information I found here I ended up with a custom aspect that looked like this and was able to be detected at runtime by reflection:
[Serializable]
[MulticastAttributeUsage(PersistMetaData = true)]
internal class AffectsProgress : OnMethodBoundaryAspect
{
public override void OnExit(MethodExecutionArgs args)
{
// do all my progress-related stuff here
}
}
Multicast attributes are by default removed during the multicasting phase and all instances (there can be quite many if you i.e. multicast to all methods) are passed internally to the Aspect Framework.
You can tell the multicast engine not to remove metadata so that you can access the attribute at runtime. This is done like this:
[MulticastAttributeUsage(PersistMetaData = true)]
Aspect attributes will then be present on declarations on which they have been applied on (i.e. MethodLevelAspect on methods, TypeLevel aspect on types, etc.).
Aspects get weaved as IL code by PostSharp, so the attributes that represent aspects have disappeared after PostSharp has done its post-processing.
The ReflectionSearch should help here (I never tried on my own), because it says:
These methods are only available at build time.
And at build time, that's the last chance to access an aspect attribute before it disappears.

Actual Performance of Fields vs. Properties

I'm doing some post-build CIL weaving that adds CIL to all methods in an assembly (in other words tons of methods). Each method checks if a specific value is null. Example (C# Reflector'd version of CIL code):
// CIL woven region start
if (MyType.Something == null) {
// ... some new stuff
}
// CIL woven region end
What is the performance impact of having MyType.Something as a Property vs. a Field? I know I've read that the C# compiler performs special optimizations and there should be no performance impact in that case...but what about in the case of direct CIL code (no C# compiler)...? Or is it the JIT compiler that allows for these optimizations (so direct CIL code still benefits)?
Will emitting OpCode.Call for the static property's accessor have poorer performance than Ldsfld (bear in mind this is across tens of thousands of invocations since every method in the assembly is woven)?
Thanks.
When developing the math library for SlimDX, we found that, on pre-.NET 3.5 SP1 frameworks, using fields for the members of the math types (such as X, Y, Z for a Vector3) gave a disproportionate performance increase over properties. In other words, the difference was noticeable for small math functions which heavily accessed properties.
This has since been improved since .NET 3.5 SP1 (see JIT inling). While I believe that the JIT prior to that will still inline small methods (properties are simply methods after all), there is a bug in the earlier frameworks that prevented inlining of methods that take or return value types.
Note that the difference, when there, is still quite small. I would still elect to use properties in all but the most performance critical cases.
The C# compiler won't optimize this, no - but the JIT compiler can usually inline trivial (and non-virtual) properties as far as I'm aware.
As with all performance questions though: when in doubt, test!
The effect is minor in either direction. If your properties look like this::
public static SomeType PropertyName
{
get {return MyType.propertyName;}
set {MyType.propertyName = value;}
}
There genuinely should be a very minor difference. The Jit compiler should inline the call MyType.set_Property into a field load, but even if it couldn't due to a bug. I'd personally err on the side of caution and stick with the property setters and getters as potentially the method body might change, and as a result the raw field access/mutation may not be enough.
If you'd like to test you can force the method you emit to use the MethodImpl that turns off inlining or optimizing. And then compare the difference, I really doubt it'll be significant.

What problems does reflection solve?

I went through all the posts on reflection but couldn't find the answer to my question.
What were the problems in the programming world before .NET reflection
came and how it solved those problems?
Please explain with an example.
It should be stated that .NET reflection isn't revolutionary - the concepts have been around in other framework.
Reflection in .NET has 2 facets:
Investigating type information
Without some kind of reflection / introspection API, it becomes very hard to perform things like serialization. Rather than having this provided at runtime (by inspecting the properties/fields/etc), you often need code-generation instead, i.e. code that explicitly knows how to serialize each of your types. Tedious, and painful if you want to serialize something that doesn't have a twin.
Likewise, there is nowhere to store additional metadata about properties etc, so you end up having lots of additional code, or external configuration files. Something as simple as being able to associate a friendly name with a property (via an attribute) is a huge win for UI code.
Metaprogramming
.NET reflection also provides a mechanism to create types (etc) at runtime, which is hugely powerful for some specific scenarios; the alternatives are:
essentially running a parser/logic tree at runtime (rather than compiling the logic at runtime into executable code) - much slower
yet more code generation - yay!
I think to understand the need for reflection in .NET, we need to go back to before .NET. After all, modern languages like like Java and C# do not have a history BF (before reflection).
C++ arguably has had the most influence on C# and Java. But C++ did not originally have reflection and we coded without it and we managed to get by. Occasionally we had void pointer and would use a cast to force it into whatever type we wanted. The problem here was that the cast could fail with terrible consequences:
double CalculateSize(void* rectangle) {
return ((Rect*)rectangle)->getWidth() * ((Rect*)rectangle)->getHeight());
}
Now there are plenty of arguments why you shouldn't have coded yourself into this problem in the first place. But the problem is not much different from .NET 1.1 with C# when we didn't have generics:
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
However, when the C# example fails it does so with a exception rather than a potential core dump.
When reflection was added to C++ (known as Run Time Type Identification or RTTI), it was hotly debated. In Stroustrup's book The Design and Evolution of C++, he lists the following
arguments against RTTI, in that some people:
Declared the support unnecessary
Declared the new style inherently evil ("against the spirit of C++")
Deemed it too expensive
Thought it too complicated and confusing
Saw it as the beginning of an avalanche of new features
But it did allow us to query the type of objects, or features of objects. For example (using C#)
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
if(shape is Rect) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
else if(shape is Circle) {
return Math.Power(((Circle)shape).Radius, 2.0) * Math.PI;
}
}
Of course, with proper planning this example should never need to occur.
So, real world situations where I've needed it include:
Accessing objects from shared memory, all I have is a pointer and I need to decide what to do with it.
Dynamically loading assemblies, think about NUnit where it loads every assembly and uses reflection to determine which classes are test fixtures.
Having a mixed bag of objects in a Hashtable and wanting to process them differently in an enumerator.
Many others...
So, I would go as far as to argue that Reflection has not enabled the ability to do something that couldn't be done before. However, it does make some types of problems easier to code, clearer to reader, shorter to write, etc.
Of course that's just my opinion, I could be wrong.
I once wanted to have unit tests in a text file that could be modified by a non-technical user in the format in C++:
MyObj Function args //textfile.txt
But I couldn't find a way to read in a string and then have the code create an object instance of the type represented by the string without reflection which C++ doesn't support.
char *str; //read in some type from a text file say the string is "MyObj"
str *obj; //cast a pointer as type MyObj
obj = new str; //create a MyObj
Another use might be to have a generic copy function that could copy the members of an class without knowing them in advance.
It helps a lot when you are using C# attributes like [Obsolete] or [Serializable] in your code. Frameworks like NUnit use reflection on classes and containing methods to understand which methods are tests, setup, teardown, etc.

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.

Is overloading the only way to have default function arguments in C#?

Is it true that the only way to handle default function arguments is through function overloading?
For example, in PHP I can do this:
function foo($x, $y=0)
{
}
Would the best way to handle it in C# be this?
void foo(int x)
{
foo(x, 0);
}
void foo(int x, int y)
{
}
Example lifted from here
Edit
Made the C# example into actual C# (Thanks Blair Conrad)
Just to satisfy some curiosity:
From Why doesn't C# support default parameters?:
In languages such as C++, a default value can be included as part of the method declaration:
void Process(Employee employee, bool bonus = false)
This method can be called either with:
a.Process(employee, true);
or
a.Process(employee);
in the second case, the parameter bonus is set to false.
C# doesn't have this feature.
One reason we don't have this feature is related to a specific implementation of the feature. In the C++ world, when the user writes:
a.Process(employee);
the compiler generates
a.process(employee, false);
In other words, the compiler takes the default value that is specified in the method prototype and puts it into the method call - it's just as if the user wrote 'false' as the second parameter. There's no way to change that default value without forcing the user of the class to recompile, which is unfortunate.
The overloading model works better in this respect. The framework author just defines two separate methods, and the single-parameter one calls the two-parameter method. This keeps the default value in the framework, where it can be modified if necessary.
It would be possible for a compiler to take something like the C++ definition and produce the overloads, but there are a few issues with that approach.
The first one is that the correlation between the code that the user writes and the code the compiler generates is less obvious. We generally try to limit magic when possible, as it makes it harder for programmers. The second issue has to do with things like XML doc comments and intellisense. The compiler would have to have special rules for how it generates doc comments for the overloaded methods, and intellisense would need to have smarts to collapse the overloaded methods into a single method.
Writing overloads yourself is a bit less convenient, but we think it's an acceptable solution.
Yes, that'd be best, except you'd omit the $s on the parameter names, as others have pointed out. For those interested in the rationale behind the lack of default parameter values, see #Giovanni Galbo's explanation.
Regarding the excerpt from the c# faq:
Most of the problems listed there were solved for VB.Net (specifically the intellisense and xml comments issues), meaning they're really red herrings-- there is code available to the C# team that will solve the problem.
Another reason has to do with forcing a user of a class to re-compile, but that's a bit of a red herring, too. If you change a default value in your framework class and the user does not have to recompile, you risk the user not knowing that the default value changed. Now you have a potential bug in the code that doesn't show up until runtime. In other words, the alternative of overloading the function is at least as bad. Of course, this also presumes a specific implementation of the feature, but it's the implementation suggested in the faq.
Therefore you have to weigh the remaining reason ("try to limit the magic") vs the fact (which they acknowledge) that writing the overloads is "a bit less convenient". Personally, I say put the feature in, and let the programmer decide whether or not to use it.
Default arguments are part of C++, but as of C# 3.5 default arguments are still not supported-- you'll have to overload. They've been available in VB.Net since 1.0.
Yes.
Or currying.
Or abstracting into a class and using default values there.
No, AFAIK C# does not support overriding, and yes, that is the recommended way of accomplishing the same effect.
As pointed out, this isn't currently available in C# however they will be present within C# 4.0 as Sam Ng discusses on his blog:
http://blogs.msdn.com/samng/archive/2009/02/03/named-arguments-optional-arguments-and-default-values.aspx
doe this not do the job?
void foo(int x):this(x, 0){}
void foo(int x, int y){
// code here
}

Categories