Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, May 15, 2011

Expressionistic copying

Recently I had the need of cloning a number of object, traditionally you’d have to use reflection based techniques if you wanted a generic solution, (unless you go really hardcore with Reflection.Emit)

The sample code below only accounts for public properties, but in many cases that isn’t enough.

Given the performance implications of using reflection, and the fact that you are allowed to include blocks in expressions in .NET 4 I figured I’d do a small experiment and micro-benchmark comparing these two approaches:

I have an entity I want to copy like so

public class Entity
{
public int Foo { get; set; }
public string Bar { get; set; }
public string Baz { get; set; }
public int Foo2 { get; set; }
public string Bar2 { get; set; }
public string Baz2 { get; set; }
public int Foo3 { get; set; }
public string Bar3 { get; set; }
public string Baz3 { get; set; }
}

I implemented reflection based copy like so (with some room for optimizations):



public class ReflectionObjectCopier : IObjectCopier
{
#region IObjectCopier Members

public void Copy<T>(T fromObj, T toObj)
{
var properties = from prop in fromObj.GetType().GetProperties(BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.FlattenHierarchy)
where prop.CanRead && prop.CanWrite
select prop;
foreach (PropertyInfo pi in properties)
{
pi.SetValue(toObj, pi.GetValue(fromObj, null), null);
}
}

#endregion
}


When using this copying 10 000 objects takes 250ms or so.



However, if I create an expression that performs the copying directly it only takes 10ms (with subsequent testruns only taking 4, when reusing the cached expression). That is a pretty decent saving if you ask me.



public class ExpressionObjectCopier : IObjectCopier
{
Dictionary<Type, object> cache = new Dictionary<Type, object>();

Action<T,T> CreateCopier<T>()
{
ParameterExpression fromParam = Expression.Parameter(typeof(T), "from");
ParameterExpression toParam = Expression.Parameter(typeof(T), "to");

LambdaExpression exp = Expression.Lambda(typeof(Action<T, T>),
Expression.Block(
from prop in typeof(T).GetProperties(BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.FlattenHierarchy)
where prop.CanRead && prop.CanWrite
select Expression.Assign(Expression.Property(toParam, prop),
Expression.Property(fromParam, prop))
),
fromParam,
toParam);

Action<T, T> copier = (Action<T, T>)exp.Compile();
cache[typeof(T)] = copier;
return copier;
}

#region IObjectCopier Members

public void Copy<T>(T fromObj, T toObj)
{
object action;
Action<T,T> copier;
if (!cache.TryGetValue(fromObj.GetType(), out action))
{
copier = CreateCopier<T>();
}
else
{
copier = (Action<T, T>)action;
}


copier(fromObj, toObj);
}

#endregion
}


The above code obviously isn’t production quality…

Tuesday, November 02, 2010

Timeline – or restyling controls

One nice thing with WPF that is slightly different is that the controls are lookless. This means that you can re-style or apply a different template altogether if the behavior of a standard control is what you want, but the looks are not.

A real world example: At work we recently needed to show a list of items with associated timestamps, in a way so that the time differences between them are easily determined at a glance.

Thanks to the lookless controls of WPF I was able to solve this simply by using a ListBox with re-templated ListBoxItems giving the following result:

image

The style is defined as follows:

        <Style TargetType="ListBoxItem" x:Key="TimelineStyle">
            <
Setter Property="SnapsToDevicePixels" Value="true"/>
            <
Setter Property="OverridesDefaultStyle" Value="true"/>
            <
Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <
Setter Property="Template">
                <
Setter.Value>
                    <
ControlTemplate TargetType="ListBoxItem">
                        <
StackPanel Orientation="Vertical"> <Border
                           
Name="Border"
                           
Padding="2"
                           
CornerRadius="2"
                           
BorderThickness="2"
                           
SnapsToDevicePixels="true">
                                <
ContentPresenter />
                            </
Border>
                            <
Grid>
                                <
Rectangle Width="2" Stroke="LightBlue"
                                          
Height="{Binding TimeToNext, Converter={StaticResource HeightConverter}}"
                                          
VerticalAlignment="Center"
                                          
HorizontalAlignment="Center"/>
                                <
TextBlock Text="{Binding TimeToNext, Converter={StaticResource DurationConverter}}"
                                          
Background="White"
                                          
VerticalAlignment="Center"
                                          
HorizontalAlignment="Center"
                                          
FontSize="8"
                                          
Foreground="Gray"/>
                            </
Grid>
                        </
StackPanel>
                        <
ControlTemplate.Triggers>
                            <
Trigger Property="IsSelected"
                                    
Value="true">
                                <
Setter TargetName="Border"
                                       
Property="BorderBrush"
                                       
Value="Blue"/>
                            </
Trigger>
                        </
ControlTemplate.Triggers>
                    </
ControlTemplate>
                </
Setter.Value>
            </
Setter>
        </
Style>

and and the listbox uses the style like this:

<ListBox ItemsSource="{Binding DataItems}" ItemContainerStyle="{StaticResource TimelineStyle}" />



The style uses two converters, but those should be fairly trivial.



Setting FocusVisualStyle to {x:Null} is done to hide the indication of keyboard focus, as unless it is fixed properly, will be more confusing than helpful. Fixing it properly is left as an exercise for the reader.

Monday, February 01, 2010

Nullable<T> and IFormattable

If you ever tried to format a nullable type you would soon realize that you cannot directly as Nullable<T> does not implement IFormattable and thus you only have object.ToString() available.

This is easily fixed using an extension method:

public static class NullableExtensions
{
public static string ToString<T>(
this Nullable<T> nullable,
string format,
IFormatProvider formatProvider)
where T : struct, IFormattable
{
if (!nullable.HasValue) return string.Empty;
T notNull = nullable.Value;
return notNull.ToString(format, formatProvider);
}
}


and you can use it e.g. like so:



            DateTime? foo = null;
...
foo.ToString("t", CultureInfo.CurrentCulture);

Monday, November 03, 2008

C# quiz 9/?

Consider the following:

Guid globallyUnique1 = new Guid();
Guid globallyUnique2 = new Guid();
if (globallyUnique1 == globallyUnique2)
{
MessageBox.Show("This cannot be");
}
else
{
MessageBox.Show("Everything is well");
}

What is shown? Why?

Thursday, April 03, 2008

C# quiz 8/?

Now it's time for some one regarding serialization:

Given this serializable class:

    [Serializable]
public class Victim {
public static int InstanceCount;
public int Data { get; set; }

public Victim() {
InstanceCount++;
Data = 2;
}
}

and the following test code:

    class Program {
static void Main(string[] args) {
Victim v = new Victim();
v.Data = 3;
BinaryFormatter serial = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
serial.Serialize(ms, v);
ms.Seek(0, SeekOrigin.Begin);
v = (Victim)serial.Deserialize(ms);
Console.WriteLine("Data {0}", v.Data);
Console.WriteLine("Instances {0}", Victim.InstanceCount);
}
}

What is the output, and why?

C# quiz 7/?

If we compile the following code to a dll, for example using the following command line:

csc.exe /t:library Library.cs

namespace Library {
public class Library {
public const int FOO = 1;
public static readonly int BAR = 2;
}
}

And refer those in our test program:

    class Program {
static void Main(string[] args) {
Console.WriteLine(Library.Library.FOO);
Console.WriteLine(Library.Library.BAR);
}
}

Now, if we change FOO to 10 and BAR to 12 and recompile Library.dll without recompiling the test program, what is the output when we run the test program?

C# quiz: 6/?

Consider the following:

    class Test {
private int m_foo;
public int Foo {
get { return m_foo; }
}
public int set_Foo(int value) {
m_foo = value;
}
}

What happens when you compile, and why?


Wednesday, April 02, 2008

C# quiz: 5/?

Consider a console application with the following Main:

        static void Main(string[] args) {
System.Threading.Timer t = new Timer(dummy =>
{
Console.WriteLine("In callback: " + DateTime.Now);
GC.Collect();

}, null, 0, 1000);

Console.ReadLine();
t = null;
}

What does the code do? Does it matter if it is compiled Debug or Release, if so, why?


(To give proper credit where credit is due, this example is heavily inspired by CLR via C# by Jeffrey Richter)


C# quiz: 4/?

Given the following code:

    internal class Test {
public int Foo { get; set; }
public int Bar { get; set; }

#if CUSTOM
public override int GetHashCode() {
return Foo.GetHashCode() ^ Bar.GetHashCode();
}

public override bool Equals(object obj) {
if (object.ReferenceEquals(obj, null)) return false;
Test t = obj as Test;
if (t != default(Test)) {
return (Foo == t.Foo) && (Bar == t.Bar);
}
return false;
}
#endif
}

and the following test code:

            Dictionary<Test, string> dict = new Dictionary<Test, string>();
Test foo = new Test { Foo = 1, Bar = 2 };
dict[foo] = "Hello World";
foo.Bar = 42;
if (dict.ContainsKey(foo)) {
Console.WriteLine("it's there");
} else {
Console.WriteLine("it's not");
}

Answer the following questions:



  1. With CUSTOM not defined, what does the test code print?

  2. If CUSTOM is defined, does it change the outcome?

  3. What if Test is changed to a struct and CUSTOM is not defined, what is the output?

  4. If Test is a struct and CUSTOM is defined, what happens?

Tuesday, April 01, 2008

C# quiz: 3/?

Consider the following class:

    internal class Test {

public int Code { get; set; }

public static bool operator ==(Test lhs, Test rhs) {
if (object.ReferenceEquals(lhs, rhs)) return true;
if (lhs == null || rhs == null) {
return false;
} else {
return lhs.Code == rhs.Code;
}
}

public static bool operator != (Test lhs, Test rhs) {
return !(lhs == rhs);
}
}

What is the outcome of the following test code, and why?

            Test test1 = new Test { Code = 42 };
Test test2 = new Test { Code = 42 };
if (test1 != test2) {
Console.WriteLine("different");
} else {
Console.WriteLine("equals");
}

Monday, March 31, 2008

C# quiz: 2/?

Continuing on the series of C# and/or .NET Framework short questions:

        private void Foo(List<int> bar) {
bar = new List<int>();
// ...
}

With the method above and the code below:

        List<int> bar = null;
Foo(bar);
if (bar != null) {
Console.WriteLine("populated");
} else {
Console.WriteLine("still null");
}
If or else ?

EDIT: fixed typo in code sample.

C# quiz: 1/?

I'm starting a series with small questions C# and/or .NET Framework related questions:

First out, NaN values:

            double foo = double.NaN;
// ...
if (foo == double.NaN) {
Console.WriteLine("NaN");
} else {
Console.WriteLine("a number");
}

If or else ?

Friday, March 14, 2008

Gotcha: Hidden [Flags] attribute on bitfield enumerations

 

Just got reminded of a still unfixed bug.

Consider an enumeration of the following kind:

    /// <summary>
/// Modes enumeration
/// </summary>
[Flags]
public enum Modes {
/// <summary>
/// Yes
/// </summary>
Foo = 1,
/// <summary>
/// No
/// </summary>
Bar = 2,
/// <summary>
/// Maybe
/// </summary>
Both = Foo|Bar
}

For the user of this enumeration, it is essential to know that it in fact is a bitfield (as specified by the FlagsAttribute).


However, both Intellisense and object browser fails to give any hint about this fact!?! (Yes, this occurs in both VS 2005 and VS 2008)


So for now, remember to document (within in the summary, so it is visible) this fact for your fellow developers.


Monday, January 14, 2008

Maximizing a WPF Window to second monitor

I'm trying to develop and application that utilizes a maximized window on the second monitor.

There's a few issues here. The first is that WPF doesn't offer the same information as WinForms about monitor configuration. WinForms has SystemInformation.MonitorCount and Screen.AllScreens[i].WorkingArea. WPF has SystemParameters.PrimaryScreen[Width/Height] and SystemParameters.VirtualScreen[Width/Height] which almost works (as long as you don't have more than two monitors) but not really. So back to using WinForms API...

Secondly, the obvious solution to display a form maximized on second screen was to me the following:

                fullScreenWindow.WindowStartupLocation = WindowStartupLocation.Manual;

Debug.Assert(System.Windows.Forms.SystemInformation.MonitorCount > 1);

System.Drawing.Rectangle workingArea = System.Windows.Forms.Screen.AllScreens[1].WorkingArea;
fullScreenWindow.Left = workingArea.Left;
fullScreenWindow.Top = workingArea.Top;
fullScreenWindow.Width = workingArea.Width;
fullScreenWindow.Height = workingArea.Height;
fullScreenWindow.WindowState = WindowState.Maximized;
fullScreenWindow.WindowStyle = WindowStyle.None;
fullScreenWindow.Topmost = true;
fullScreenWindow.Show();

However, when you try that you'll end up with a topmost maximized window on your primary display, which was not what we wanted.


Turns out that we cannot maximize the window until it's loaded. So by hooking the Loaded event of fullScreenWindow and handling the event along the lines of:

        private void Window_Loaded(object sender, RoutedEventArgs e) {
WindowState = WindowState.Maximized;
}

...it works.


Oh, and you want to make certain that you are running a dual monitor configuration so you do not put the window somewhere where it is off-screen.

Wednesday, January 09, 2008

UIAutomation - testing Calculator

I recently discovered that the UIAutomation library provided in .NET 3.0 doesn't only work for managed code but for any code.

Should you so be inclined, here's how to test that calc.exe provided by Windows in fact can calculate 2+2 correctly.

        [TestMethod]
public void TestAddTwoAndTwo() {

Process calc = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = @"c:\windows\system32\calc.exe";
calc.StartInfo = startInfo;
calc.Start();
Thread.Sleep(500);

AutomationElement window = AutomationElement.FromHandle(calc.MainWindowHandle);
AutomationElement twoButton = FindAutomationElementByName(window, "2");
AutomationElement plusButton = FindAutomationElementByName(window, "+");
AutomationElement equalsButton = FindAutomationElementByName(window, "=");

AutomationElement editField = window.FindFirst(TreeScope.Descendants, new AndCondition(
new PropertyCondition(AutomationElement.ClassNameProperty, "Edit"),
new PropertyCondition(AutomationElement.IsValuePatternAvailableProperty, true)));
calc.WaitForInputIdle();

InvokePattern clickTwo = twoButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
InvokePattern clickEquals = equalsButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
InvokePattern clickPlus = plusButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;

clickTwo.Invoke();

clickPlus.Invoke();

clickTwo.Invoke();

clickEquals.Invoke();
ValuePattern pattern = editField.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;

Assert.AreEqual(4, int.Parse(pattern.Current.Value,NumberStyles.AllowDecimalPoint|NumberStyles.AllowTrailingWhite));
}
        public AutomationElement FindAutomationElementByName(AutomationElement parent, string name) {
Condition c = new PropertyCondition(AutomationElement.NameProperty, name);
return parent.FindFirst(TreeScope.Descendants, c);
}


You'll also want a reference to UIAutomationClient.dll and the following using:

using System.Windows.Automation;

To find out what the application under test has eaten i.e. how to automate it, do use UISpy.exe provided with the Windows SDK .


And yes, the syntax is a tad verbose ...

Sunday, January 06, 2008

LINQ - DataContext.Dispose()

I'm playing around with LINQ for the moment. Actually I tried Entity Framework first, but could not get that to behave as I wanted (that is Table Per Class), so I let that rest for a while until they fix TPC support in a subsequent version and tried "plain" LINQ instead.

I can't say I'm really there yet, but one thing that bit me was that I out of old habit (or whatever) used code similar to the following:

            using (DataClassesDataContext db = new DataClassesDataContext();
{
return (from user in db.Users
where user.Name == name
select user).SingleOrDefault();
}

..and I thought that all was well. However, when testing a little bit more I got  ObjectDisposedException:s when returning

return (from user in db.Users select user).AsEnumerable();

instead of

return (from user in db.Users select user).ToList();

Turns out that even though DataContext implements IDisposable, you should not use a DataContext in a using statement or directly call .Dispose() or you'll end up with lots of brokenness.


(In addition I got all kinds of attaching and detaching issues, but I think I've sorted them now. Did I already tell you that this is my first attempt of using LINQ non-trivially?)

Saturday, December 22, 2007

TimeSpan.Seconds vs .TotalSeconds

The difference between the Seconds property and the TotalSeconds property is (or at least should be) pretty obvious, but based on experience it is a common bug to use .Seconds when you actually mean .TotalSeconds. For the readers out there that hasn't gotten the difference, think of a timespan of value 1 minute 23 seconds - here .Seconds is 23 and total seconds is 83.

As a rule of thumb, most often it's the Total variant you want, and yes, the same applies to all the other members too, (e.g. .Minutes, .Milliseconds vs. the corresponding .Total-prefixed ones)

Friday, December 21, 2007

"Practical Functional C#"

I just found an interesting blog post series about practical functional C#. It starts right here. Maybe I've missed something, but this feels like a fresh breath, being really down to earth and real world. I'm looking forward to future posts.

Friday, December 14, 2007

"Is there a constant for tab like Environment.Newline?"

..was a question a co-worker asked the other day. My first answer was no, as it is not really needed as a tab does not change between platforms as newline might (think Mono).

Then I realized, there actually *is* one, so I gave the following instructions:

  • Add a reference to Microsoft.VisualBasic.dll
  • add a using Microsoft.VisualBasic; statement
  • use Constants.vbTab

(And to avoid any misunderstandings, no, this was not a serious suggestion.)

Wednesday, November 28, 2007

Interesting findings ...

What would you say if you found a class with the following interface during a code review?

internal static class Internal
{
// Methods
private static void CommonlyUsedGenericInstantiations_HACK();
private static T NullableHelper_HACK<T>() where T : struct;
private static void SZArrayHelper_HACK<T>(SZArrayHelper oSZArrayHelper);
}

Suspicious to say the least ...


The 'interesting' part here, is that the class actually exists, and not just anywhere but as System.Internal in mscorlib !