Well just got the release version of VS2010 installed and all I can say is “OMG”.  Not an OMG as in “OMG that is so cool!”, but more like an “OMG, are you serious?”.
 
Several things are standing out as wickedly wrong before I even open a solution…
 
My hardware is no longer sufficient.  I’m running on an HP Pavilion notebook about 2yrs old. Running a dual-core 2.2ghz (3gb RAM) with Vista SP2 32-bit.  Just moving my mouse through menus and around the UI, dragging windows, etc is painful and eating 30-50% of my CPU.  Now I know it’s not stellar machine but my mouse jumping several inches at a time is crazy unusable.  Since I don’t time or money to buy new hardware right now I’ve disable the Vista Areo and reverted to the Windows 2000 look and feel.  Things are moving much better now… Almost usable if ugly.  The scrolling speed of source code is still nasty slow. So word to the wise if you scoring below 3.0 on the “Windows Experience Index” for “3D business and gaming graphics performance” your probably in for a hardware update.
 
Tabbed documents, I hate them.  Unfortunately for me Microsoft is cramming another user experience change down my throat.  Like that @#^*ing ‘Ribbon bars’ interface in Office there is no way to turn it off in VS2010.  (I actually quit using MS Office and switched to OOo to avoid ribbons).  It’s cool that you make the source window float out of the app, but I’m still going to desperately miss the good-old-fashioned MDI view.
 
I’m sure that over the comming days, weeks, and years I’ll find much more to hate and love about about VS2010, but so far I’m not a fan. I guess I’ll go take some time to get to know VS2010 a little better and see if my initial reaction changes.  I hate to think what the next GUI design change from MS will entail for me … I guess I’m just old and set in my ways.
 
LOL, at least I’m not the only one: What happened to MDI capability in the editor?

 

Changes in this version:

  • CSBuild initial release – a command-line compilation utility that drives MSBuild to compile designated project files.
  • Added Library.Cloning namespace to support deep-object cloning of any object using either memberwize or serializable copy.
  • Added Library.Collections.ReadOnlyList to provide a read-only collection interface and implementation.
  • Added Library.Collections.OrdinalList to provide a collection of integers stored as a bit-array that can be operated on as a set (intersect/union/etc).
  • Added Library.Collections.SetList to provide a generic collection of that can be operated on as a set (intersect/union/etc).
  • CommandInterpreter can now read SET operations from stream, also added an IgnoreMember attribute.
 

This implementation makes heavy use of the FormatterServices object used by serialization:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices_members.aspx

It provides several helpful methods in this case that are aware of custom serialization options like [NonSerialized]. In the case of an object not being marked [Serializable] you have to create field list manually. Here is an example shallow object clone:

using System.Runtime.Serialization;
using System.Reflection;

    static class Clonable
    {
        public static T Clone<T>(this T instance)
        {
            object copy;
            Type type = instance.GetType();

            if (instance is ICloneable)
                return (T)((ICloneable)instance).Clone();

            List<MemberInfo> fields = new List<MemberInfo>();
            if (type.GetCustomAttributes(typeof(SerializableAttribute), false).Length == 0)
            {
                Type t = type;
                while (t != typeof(Object))
                {
                    fields.AddRange(t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly));
                    t = t.BaseType;
                }
            }
            else
                fields.AddRange(FormatterServices.GetSerializableMembers(instance.GetType()));

            copy = FormatterServices.GetUninitializedObject(instance.GetType());
            object[] values = FormatterServices.GetObjectData(instance, fields.ToArray());
            FormatterServices.PopulateObjectMembers(copy, fields.ToArray(), values);

            return (T)copy;
        }
    }

As with anything, use this carefully. This method run against some objects will cause native handles to be copied and can then lead to application crashes in unmanaged code.

If you need a deep clone things get a lot more complicated. I don’t recommend it; rather you should insist that objects are decorated with [Serialiable] and simply use serialization to copy the object. That being said, I will post a working deep-clone as a follow up to this post.