I have done it again. In order to work on a particular project, I have been sidetracked into writing a utility to help me continue with what I am actually trying to do. In my defense, I did look around the net for an application that would do what I needed so I didn't have to write it, but no application seemed appropriate.
In essence, I need an application to resolve all the links internal to a website and check their status. This will give me an initial view of the state of the site. I then want to take all of those links and replay the analysis of those resolved links using a different base address. The reason I am doing this is because I am looking at migrating my Community Server based blog to use BlogEngine.Net instead. As part of that migration, I want to maintain as much of the Community Server url formats as possible so I don't lose my existing audience.
Given that this application is going to chew a lot of bandwidth (my entire site) along with the need for accurate results, I want to make sure that this utility is doing the right thing. Unit testing is critical for this to be successful. I quickly found however that my initial cut is not very testable.
Here is a simple example of how to take untestable code and make it testable. In the following examples, there is some logic in the ResourceResolver.GetResourceContents method that we want to test.
The untestable example
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
ResourceResolver resolver = new ResourceResolver();
Uri location = new Uri("http://localhost");
String content = resolver.GetResourceContents(location);
Debug.WriteLine(content);
}
}
internal class ResourceResolver
{
public String GetResourceContents(Uri location)
{
HttpWebRequest request = HttpWebRequest.Create(location) as HttpWebRequest;
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (Stream contentStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(contentStream))
{
String content = reader.ReadToEnd();
// Do something with this value
return content;
}
}
}
}
}
This is untestable as a unit test. To write a test for this code will require an integration test as requests are being made to an external resource (http in this case). What if that resource is not available or produces unknown or unmanageable results? Unit testing normally requires more flexibility as the same code paths need different data thrown at them.
This code is a classic example. The HttpWebRequest class is not easily testable. Converting this code so that mocks and stubs can be used will allow unit tests to be supported.
The testable example
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
HttpResourceLoader loader = new HttpResourceLoader();
ResourceResolver resolver = new ResourceResolver(loader);
Uri location = new Uri("http://localhost");
String resourceContent = resolver.GetResourceContents(location);
Debug.WriteLine(resourceContent);
}
}
public interface IResourceLoader
{
String GetResourceContents(Uri location);
}
public class HttpResourceLoader : IResourceLoader
{
public String GetResourceContents(Uri location)
{
HttpWebRequest request = WebRequest.Create(location) as HttpWebRequest;
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (Stream contentStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(contentStream))
{
return reader.ReadToEnd();
}
}
}
}
internal class ResourceResolver
{
public ResourceResolver(IResourceLoader loader)
{
Loader = loader;
}
public String GetResourceContents(Uri location)
{
String content = Loader.GetResourceContents(location);
// Do something with this value
return content;
}
private IResourceLoader Loader
{
get;
set;
}
}
}
By abstracting an implementation that actually gets the resource contents (with a bit of Dependency Injection thrown in), we now have a ResourceResolver.GetResourceContents method that can be unit tested. The unit testing involved now needs to pass in either a stub or a mocked instance of IResourceLoader and we can safely test the logic of this method without requiring http requests.
When you develop code, please think about how it is going to be tested. Even better, write unit tests when you develop the code. You will quickly find out how flexible your code is for unit testing.
I read the Visual Studio Tip: Disable F1! post a few weeks ago and was very tempted to take the advice to remove the F1 keyboard mapping in Visual Studio. I kept it because sometimes I do actually want to open help. The problem is I keep missing ESC and hitting F1.
I've finally cracked. It is just too annoying, especially when you haven't opened help yet and it takes a long time to come up. I've got a different take on the solution though. Because I still want access to help, rather than removing the F1 keyboard mapping, I've changed it to F1, F1. A double tap on the F1 key is much more deliberate.
Kudos to Andrew Stevenson who inadvertently provided the title to this blog in his comment in the above mentioned post.
Read the 'official' interview here.
I really don't know what to think about this. I definitely don't like the phrase "free for download" because it can be very misleading. James Moore has been more explicit in other posts by saying that existing functionality will remain free for download and use. I'm supportive of this move if this is the case and I hope that Red Gate can add value to this product. While it is one of the best .Net tools around, it isn't perfect.
I think this brings great risk to Red Gate. Any serious developer has Reflector as their #1 tool and I am confident that the percentage of good developers out there is substantial. It will be really bad publicity for Red Gate if they tick off that number of people in the industry. Everyone wins if they make the right moves though.
On that point, Red Gate is spending the next couple of months asking the community about what they should do with Reflector. Want to be heard by Red Gate? Flood the forum and let them know how you want this to play out.
I hope that Lutz was well paid for this product. He deserves every cent for how he had supported the industry for so many years.
Hmmm, not sure about this one. I was installing VS2008 SP1 this morning and this came up.
Updated: Microsoft have responded here.
There are several issues that can prevent trace data being written. Here are a few of that you might encounter.
TraceSource names
If using TraceSource, the name provided to the TraceSource constructor is case sensitive. If the string doesn't match your configuration exactly, a default TraceSource instance is created rather than the configured one you were expecting.
TextWriterTraceListener
If using TextWriterTraceListener (or XmlWriterTraceListener that derives from it), there are several more issues that can occur.
The following code is the code in TextWriterTraceListener that causes the issues.
public override void WriteLine(String message)
{
if (EnsureWriter())
{
if (base.NeedIndent)
{
WriteIndent();
}
writer.WriteLine(message);
base.NeedIndent = true;
}
}
internal Boolean EnsureWriter()
{
Boolean flag = true;
if (writer == null)
{
flag = false;
if (this.fileName == null)
{
return flag;
}
Encoding encodingWithFallback = GetEncodingWithFallback(new UTF8Encoding(false));
String fullPath = Path.GetFullPath(this.fileName);
String directoryName = Path.GetDirectoryName(fullPath);
String fileName = Path.GetFileName(fullPath);
for (Int32 i = 0; i < 2; i++)
{
try
{
writer = new StreamWriter(fullPath, true, encodingWithFallback, 0x1000);
flag = true;
break;
}
catch (IOException)
{
fileName = Guid.NewGuid() + fileName;
fullPath = Path.Combine(directoryName, fileName);
}
catch (UnauthorizedAccessException)
{
break;
}
catch (Exception)
{
break;
}
}
if (!flag)
{
this.fileName = null;
}
}
return flag;
}
When writing a record, it ensures that the writer is ready. The biggest problem with this implementation is that the logic in EnsureWriter() swallows any exception. If an exception is encountered, a second attempt is made which is likely to fail for the same reason as the first attempt. This causes WriteLine() to skip out without throwing an exception.
I find this code very poor. If there is a problem with using the configuration values, the developer (or operations staff) need to know what the problem is so they can fix it. This implementation simply just ignores the request to write the trace record when an exception is encountered. This is the primary reason that troubleshooting tracing problems is so difficult.
Some of the problems that can be encountered with the TextWriterTraceListener and derived classes are:
- The configured directory doesn't exist. I would have expected that this code would ensure that the directory is created, but unfortunately it doesn't.
- Lack of permissions. If the identity running the trace methods doesn't have permissions to write to the configured location, this will obviously fail.
- The path is too long. The .Net framework doesn't support paths more than 260 characters. See here.
- The drive specified in the path doesn't exist
Hope this helps.
The yield statement is one of those C# statements that is really powerful but is either not understood or is unknown to most developers. Raymond Chen just posted a very good write up on how the compiler deals with the yield statement.
The Old New Thing : The implementation of iterators in C# and its consequences (part 1)
The great feature that the yield statement brings is delayed execution in iterations. If building a collection of items to iterate through is an expensive operation on either performance or memory, getting individual items as they are requested may be a better design. Using the yield statement means that this is really easy to achieve.
Take the following code for example:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
Console.WriteLine("Starting the iterations");
foreach (Entity item in GetItems(10))
{
Console.WriteLine("Got item {0} - {1} - {2}", item.Id, item.FirstValue, item.SecondValue);
}
Console.ReadKey();
}
private static IEnumerable<Entity> GetItems(Int32 maxItems)
{
for (Int32 index = 0; index < maxItems; index++)
{
yield return GetItemFromStore(index);
}
}
private static Entity GetItemFromStore(Int32 id)
{
Console.WriteLine("Getting item {0} from the store", id);
// Simulate getting the item from a data store or service
Entity item = new Entity();
item.Id = id;
item.FirstValue = "First" + id;
item.SecondValue = "Second" + id;
return item;
}
}
internal class Entity
{
public String FirstValue
{
get;
set;
}
public Int32 Id
{
get;
set;
}
public String SecondValue
{
get;
set;
}
}
}
This code iterates over a set of 10 items and outputs the details of each item encountered. The interesting bit is that each item is only requested and created for each iteration rather than calculating the entire set up front.
The output of this code is:
Starting the iterations
Getting item 0 from the store
Got item 0 - First0 - Second0
Getting item 1 from the store
Got item 1 - First1 - Second1
Getting item 2 from the store
Got item 2 - First2 - Second2
Getting item 3 from the store
Got item 3 - First3 - Second3
Getting item 4 from the store
Got item 4 - First4 - Second4
Getting item 5 from the store
Got item 5 - First5 - Second5
Getting item 6 from the store
Got item 6 - First6 - Second6
Getting item 7 from the store
Got item 7 - First7 - Second7
Getting item 8 from the store
Got item 8 - First8 - Second8
Getting item 9 from the store
Got item 9 - First9 - Second9
Very powerful, very easy.
I have been writing up some instrumentation documentation where I have been explaining the use of TraceFilter implementations. I gave an example of creating a TraceFilter that filters trace events from the TraceListener based on the identity of the executing thread. The issue here is that a TraceListener implementation may be writing its data on a different thread to the one that invoked the trace event.
I had always assumed that when you create a new thread, the identity of the creating thread is used as the identity of the new thread. There is a lot of danger in assumptions though. While it's just an example, I needed to prove that my TraceFilter code wouldn't be invalid if a TraceListener did use threads for its work.
After firing up Reflector, I poked around Thread.CurrentPrincipal code. As expected, the principal is stored in the context data of the thread (LogicalCallContext via CallContext). What was interesting about the code is that if the call context doesn't contain a principal, it then consults the AppDomain. In the internal AppDomain.GetThreadPrincipal() method, the code runs a switch around a PrincipalPolicy value. I hadn't come across PrincipalPolicy before so this was an interesting discovery.
The policy allows for an AppDomain to determine the default identity to use for threads. This is set by calling AppDomain.SetPrincipalPolicy(), but its value is only valid until an identity is explicitly assigned to a thread. From that point on, that thread and any threads that it creates use the explicitly defined identity. The way to revert this back to using the policy on the AppDomain is to set the identity on the current thread to null.
So my assumption was correct. Identities on threads do get propagated to their created threads.
Here is an example:
using System;
using System.Security.Principal;
using System.Threading;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
Thread newThread = new Thread(ThreadTest);
newThread.Start("Default AppDomain");
newThread.Join();
Console.WriteLine();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.NoPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain NoPrincipal");
newThread.Join();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.UnauthenticatedPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain UnauthenticatedPrincipal");
newThread.Join();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain WindowsPrincipal");
newThread.Join();
Console.WriteLine();
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("NewIdentity"), null);
Console.WriteLine("Assigned new identity to thread");
Console.WriteLine();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.NoPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain NoPrincipal");
newThread.Join();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.UnauthenticatedPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain UnauthenticatedPrincipal");
newThread.Join();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain WindowsPrincipal");
newThread.Join();
Console.WriteLine();
Thread.CurrentPrincipal = null;
Console.WriteLine("Removed identity from thread");
Console.WriteLine();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.NoPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain NoPrincipal");
newThread.Join();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.UnauthenticatedPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain UnauthenticatedPrincipal");
newThread.Join();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
newThread = new Thread(ThreadTest);
newThread.Start("AppDomain WindowsPrincipal");
newThread.Join();
Console.ReadKey();
}
private static void ThreadTest(Object value)
{
IPrincipal principal = Thread.CurrentPrincipal;
String name = "null";
if (principal != null
&& principal.Identity != null)
{
name = principal.Identity.Name;
if (String.IsNullOrEmpty(name))
{
name = "empty";
}
}
Console.WriteLine(value + " - " + name);
}
}
}
The results in the following output (with the windows account removed):
Default AppDomain - empty
AppDomain NoPrincipal - null
AppDomain UnauthenticatedPrincipal - empty
AppDomain WindowsPrincipal - [WindowsAccountRemoved]
Assigned new identity to thread
AppDomain NoPrincipal - NewIdentity
AppDomain UnauthenticatedPrincipal - NewIdentity
AppDomain WindowsPrincipal - NewIdentity
Removed identity from thread
AppDomain NoPrincipal - null
AppDomain UnauthenticatedPrincipal - empty
AppDomain WindowsPrincipal - [WindowsAccountRemoved]
A few months ago I did some research into dependency injection frameworks. One of the interesting features provided by many of the DI frameworks was the support for AOP. This is really interesting stuff and great for injecting logging and caching implementations without having to modify existing code.
There are several AOP implementations around (Oren Eini identified seven in this post) and I have always wondered how some of them worked. Unfortunately I never got the time to research it.
Using aspects in .NET - Part 1 is a post by Istvan that just popped up in my feed reader. He describes how to create an AOP implementation using ContextBoundObject and ProxyAttribute classes. I didn't previously know that combining these types in the .Net framework allows you to override the new statement. This is extremely powerful. I had assumed that this was the method that TypeMock used for creating unit testing mocks, but Oren's post identifies it as using a profiling API.
I think the centerpiece of Istvan's implementation is the RealProxy class. This is another one of those .Net classes that is incredibly powerful. I have used RealProxy before to create a wrapper for WCF channel management. Thankfully this helped me to understand Istvan's post quickly. I am looking forward to his Part 2 post.
The only thing I don't like about this style of AOP is that it requires the aspected class to derive from ContextBoundObject and have a ProxyAttribute derived attribute decorated on the class. This has the disadvantage that the aspected class must be not only designed for AOP, but coded for this specific type of AOP. I'm a fan of POCO code design, so at this stage I think the profiling API version of AOP used by TypeMock is so much more powerful and has less impact on the code.
BTW, Castle Windsor was my pick of the dependency injection frameworks as it was the most suitable for my requirements. I also did some research into mocking frameworks about the same time. While TypeMock was certainly the most powerful, its particular implementation isn't very flexible. Oren's RhinoMocks was my pick on that one.
I'm working on a new Visual Studio addin that launches a profiling application that in turn runs unit and load tests. I can't recall how I created the project, but it must not have been by using the addin wizard. When I debugged the addin in another instance of Visual Studio, I got an error indicating that the addin couldn't be loaded or threw an exception. The additional information it gave was "No such interface supported".
After pulling my hair out for quite a while, the answer was that the AssemblyInfo.cs contained the following:
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
Visual Studio is written mostly in the COM world, including the functionality that resolves and loads addins. This attribute hides the addin from Visual Studio. It therefore can't find the interface it is expecting when it attempts to load the addin from the configured type information. Removing this attribute from AssemblyInfo.cs (it is included by default) or setting its value to true will allow Visual Studio to correctly load the addin.
I have just released the ReSharper Plugins 1.0 in my NeovolveX extensibility project on CodePlex. This plugin formats code as part of the ReSharper code format profiles.
The following is a copy of the Using ReSharper Plugins 1.0 documentation on the project site
Value Type Alias Formatter
The ReSharper Plugins project currently contains a single plugin that provides C# code formatting functionality. This formatting function allows for type declarations to be formatted between their alias type and their CLR type. For example, depending of the format settings defined in a code cleanup profile, bool can be converted to Boolean or Boolean converted to bool.
Configuration
The following displays the normal code format profile dialog.

When the plugin is installed, the code format profile dialog will include an additional format option called Type alias conversion.

The type conversion options are:
- Do not change - No change is made to the code
- Convert to alias type - References of CLR types are converted to their alias types (Boolean to bool for example)
- Convert from alias type - References of alias types are converted to their CLR types (bool to Boolean for example)
The Do not change setting is the default value.
Type mappings
The following are the type mappings that are supported for converting types between alias types and their CLR types.
| Alias type | CLR type |
| object |
Object |
| char |
Char |
| string |
String |
| bool |
Boolean |
| byte |
Byte |
| short |
Int16 |
| int |
Int32 |
| long |
Int64 |
| ushort |
UInt16 |
| uint |
UInt32 |
| ulong |
UInt64 |
| double |
Double |
| decimal |
Decimal |
| float |
Single |
| sbyte |
SByte |
Code examples
Code formatted to use alias types

Code formatted to use CLR types
Grab it from here.
I've written some code that reflections MethodInfo objects from a type using its name and signature. This has been working well and all unit tests have passed, until now.
Consider the following code:
internal interface IBaseInterface
{
void GetSomething();
}
internal interface IDerivedInterface : IBaseInterface
{
void DoSomethingElse();
}
Does interface inheritance exist?
Much to my amazement, the answer is no, at least according to reflection. This is completely not what I had assumed.
Does it matter? Normally, probably not. The reason is that most people are dealing with concrete types. As concrete types provide implementations of the methods that are defined by their interfaces, the type correctly returns the expected MethodInfo objects from Type.GetMethods().
Interfaces behave very differently. If you call Type.GetMethods() on IDerivedInterface then you will be missing the methods defined in IBaseInterface. I expected that IDerivedInterface had a base type of IBaseInterface and inherited its methods. I made this assumption because that is the affect that IDerivedInterface has on types that implement it. There is an inheritance behaviour as the concrete type must implement methods for both interfaces.
What is interesting is that IDerivedInterface doesn't have a base type, and Type.GetMethods() doesn't return IBaseInterface methods. IDerivedInterface does however indicate that it implements the IBaseInterface interface.
Now things get a little curly here. An interface that implements an interface doesn't need to provide any implementation (it can't, its an interface) or do anything to satisfy implementing the interface. This makes me think that interfaces neither implement other interfaces, or inherit from them.
Here is the complete source:
using System;
using System.Reflection;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
// _______________________________________________________
//
// Base Interface test
// _______________________________________________________
Type baseInterfaceTest = typeof(IBaseInterface);
// This returns 1 method
MethodInfo[] baseInterfaceMethods = baseInterfaceTest.GetMethods();
// This returns false
Boolean baseInterfaceHasBaseClass = baseInterfaceTest.BaseType != null;
// This returns null
Type[] baseInterfaceInterfaces = baseInterfaceTest.GetInterfaces();
// _______________________________________________________
//
// Derived Interface test
// _______________________________________________________
Type derivedInterfaceTest = typeof(IDerivedInterface);
// This will only return 1 method
MethodInfo[] derivedInterfaceMethods = derivedInterfaceTest.GetMethods();
// This returns false
Boolean derivedInterfaceHasBaseClass = derivedInterfaceTest.BaseType != null;
// This returns 1 interface type
Type[] derivedInterfaceInterfaces = derivedInterfaceTest.GetInterfaces();
// _______________________________________________________
//
// Derived Type test
// _______________________________________________________
Type derivedTypeTest = typeof(DerivedType);
// This will return 2 methods (in addition to the 4 from System.Object)
MethodInfo[] derivedTypeMethods = derivedTypeTest.GetMethods();
// This will return true (System.Object)
Boolean derivedTypeHasBaseClass = derivedTypeTest.BaseType != null;
// This returns 2 interface type
Type[] derivedTypeInterfaces = derivedTypeTest.GetInterfaces();
}
}
internal interface IBaseInterface
{
void GetSomething();
}
internal interface IDerivedInterface : IBaseInterface
{
void DoSomethingElse();
}
internal class DerivedType : IDerivedInterface
{
public void DoSomethingElse()
{
}
public void GetSomething()
{
}
}
}
I had a bit of a slipup yesterday. I had a set of changes that I was relating to two different work items. I realised that I really should split up the check-in into two check-ins so that the code files are better related to their work items. What I didn't do before checking in both changesets was updating the comments of the check-ins before I committed them.
After realising my mistake, I wondered if I could change the comment of a changeset. Thankfully the answer is yes. After finding the changesets by looking at the history in TFS, I was able to simply adjust the comment to be more appropriate to the changeset and click Save. Simple.
I've just hit the foreach code coverage issue again in one of my unit tests (see my Code coverage doesn't like foreach loops post). To ensure that my tests were correctly covering all possibilities, I had to change the foreach loop into a for loop and run the test again.
The issue in this case is that the collection object I was referencing was ConfigurationElementCollection which implements ICollection. Unfortunately, this type doesn't expose an indexer property. In order to test the code coverage metrics using a for loop, I first had to create an array of the appropriate length and copy across the items across.
After running the test again, I had 100% code coverage. I have now confirmed that the missing blocks in coverage are a result of the foreach statement rather than an issue with my unit test. Now the question is do I remove the additional code and redundant array copy ? The reasons to convert the code back to the foreach loop are:
- Cleaner code
- Less bloat
- More understandable
- Code coverage shouldn't define coding style
The second point is guaranteed to get some people in a flap. To be clear, I am not saying that testability shouldn't have a bearing on coding style, I'm saying that code coverage shouldn't define coding style. While this post is about code coverage, I should also point out that code coverage doesn't really mean much by itself. It is just an indicator.
In this case, the unit tests were valid and covered all the angles, so the question is purely whether a code coverage metric is important enough to modify the code.
Another thing also comes to mind. What about performance? By using the array, I have the additional overhead of creating an array and populating it from the ICollection, but then I have the performance gain from not using the IEnumerator invoked by the foreach statement.
A quick test gave me a suitable answer.
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(String[] args)
{
Collection<String> items = new Collection<String>();
for (Int32 index = 0; index < 10; index++)
{
items.Add(Guid.NewGuid().ToString());
}
Stopwatch watch = new Stopwatch();
const Int32 Iterations = 10000;
Thread.Sleep(1000);
watch.Start();
for (Int32 index = 0; index < Iterations; index++)
{
foreach (String item in items)
{
Debug.WriteLine(item);
}
}
watch.Stop();
Console.WriteLine("foreach took {0} ticks", watch.ElapsedTicks);
watch.Reset();
watch.Start();
for (Int32 index = 0; index < Iterations; index++)
{
String[] newItems = new String[items.Count];
items.CopyTo(newItems, 0);
for (Int32 count = 0; count < newItems.Length; count++)
{
Debug.WriteLine(newItems[count]);
}
}
watch.Stop();
Console.WriteLine("for took {0} ticks", watch.ElapsedTicks);
Console.ReadKey();
}
}
}
Each time I run this test, the for loop runs at 70% of the time of the foreach loop, even with the array copy.
While code coverage by itself is not enough to make me change my coding style, a performance improvement and more accurate code coverage is a good enough reason.
Here's a tip for young players. You may find that getting the latest WiX 3.0 beta from here gives you an error saying that you need to have a version of Visual Studio installed that is above the Express edition. I have Team Suite installed, so it should be a problem. After lots of research, I came across this post which gave me the answer. It wasn't a problem with the version of Visual Studio that I had installed, it was because latest build published on the SourceForge download page was prior to their support of x64 systems. After downloading the latest build published here, it's all good.
One of my most used feature in the 3.5 compiler for .Net is automatic properties. In case you are not familiar, here is a recap.
Traditionally, properties work with a backing field. For example:
private String _someValue;
public String SomeValue
{
get
{
return _someValue;
}
set
{
_someValue = value;
}
}
Automatic properties under the 3.5 compiler allow this code to be represented as:
public String SomeValue
{
get;
set;
}
Automatic properties make code cleaner and easier to use. Additionally, they also require less testing. There isn't any point testing their logic of accessing the backing field to ensure correct operation and they appear with 100% code coverage. My biggest gripe though is that they don't truly support readonly definitions.
The documentation on MSDN says:
Auto-implemented properties must declare both a get and a set accessor. To create a readonly auto-implemented property, give it a private set accessor.
The implementation of automatic properties by the compiler define that readonly automatic properties are achieved by assigning a private scope to the set accessor. For example:
public String SomeValue
{
get;
private set;
}
Unfortunately, I think this is a cheap bandaid hack. It doesn't make the property truly readonly. It is technically readonly, but only from the perspective of external callers. Internal to the class, the property is not readonly because the private scope makes setting the property value possible. This doesn't protect the value of the backing field which is what a true readonly property should be able to support. See here for the MSDN documentation on the readonly keyword.
I would like to see this changed. Without understanding the complexities of writing compilers, I would think that this change would not be too significant. The simple fix would be to enhance the syntax of the automatic property setter definition. If the private set statement could be enhanced to understand a readonly keyword, then the compile could mark the backing field with the same readonly keyword. For example:
public String SomeValue
{
get;
private readonly set;
}
This would then be interpreted by the compiler as something like this:
private readonly String _someValue;
public String SomeValue
{
get
{
return _someValue;
}
set