Feeds:
Posts
Comments

Archive for the ‘C#/.NET’ Category

This is based on a recent thread on the MSDN forums. Someone had code that looked like this:

public class CustomObject<T>
{
    Object _obj;

    public Object Value
    {
        get
        {
            return _obj;
        }
    }

    public static explicit operator CustomObject<T>(T obj)
    {
        return new CustomObject<T>() { _obj = obj };
    }
}

class App
{
    static void Main()
    {
        var tmp1 = (CustomObject<Object>)true; // from bool

        var tmp2 = (CustomObject<Object>)12; // from int

        // The following code throws a System.InvalidCastException
        // Unable to cast object of type 'System.Object' to
        // type 'CustomObject`1[System.Object]'
        var tmp3 = (CustomObject<Object>)new Object(); // from object
    }
}

The code compiles fine but the third conversion results in an InvalidCastException. And he was quite puzzled by it.

The answer is simple if you think about it, and the exception that’s thrown is a dead giveaway. When you have an object there, the compiler sees that as a downcast (casting from base to a more derived type). The reason is that CusObject<T> is derived from Object (implicitly) and so when the type being converted is Object, it will not call the explicit (or implicit) conversion operator, instead it will generate a castclass IL instruction which will obviously fail.

To make that more clear, forget the “generics” and take this example:

class Base
{
}

class Derived : Base
{
    public static explicit operator Derived(Base b)
    {
        return new Derived();
    }
}

That will not compile and you’ll see this:

Error 1 ‘Derived.explicit operator Derived(Base)’: user-defined conversions to or from a base class are not allowed

Of course when you use a generic parameter, the compiler cannot anticipate that you’d try doing this, and so it will let you declare the operator. And when you later have an ambiguous situation where you cast from base to derived, it will simply ignore the explicit operator and instead do a downcast.

In the MSDN thread, Louis.fr pointed out the appropriate section in the language spec that talks about this. For those interested it’s 10.10.3. Quoting below:

However, it is possible to declare operators on generic types that, for particular type arguments, specify conversions that already exist as pre-defined conversions.

In cases where a pre-defined conversion exists between two types, any user-defined conversions between those types are ignored.

Read Full Post »

There was a recent thread in the MSDN forums where someone was concerned about the behavior of Type.GetElementType. His example was similar to the following:

char [][,][] arr = new char[2][,][];
Console.WriteLine(arr.GetType().GetElementType());

The output he got was:

System.Char[][,]

This puzzled him no end because the element type is clearly char[,][]. He was wondering if this was a bug in GetElementType or even if it was a bug in the C# compiler (incorrectly parsing the array declaration).

Well there is no mystery here. Array types (or rather the runtime type for an array) have a ToString implementation that displays the array using a display format closely resembling the IL syntax for arrays, and not the C# syntax. This is very easily verified with the following code:

Console.WriteLine(typeof(char[][,][,,]));

The output here is:

System.Char[,,][,][]

This is a good idea since the C# array syntax is not universal among CLI languages anyway. Both VB.NET and C++/CLI use array syntax that’s different from this.

Read Full Post »

This question or a similar variation pops up in the forums once in a while. The core problem is that while null terminated char arrays can be marshaled to a System.String fairly easily, with other unmanaged arrays the marshaller cannot know for sure what size of array to create. The solution is to marshal the argument as an IntPtr and then in the calling code, the user can manually create a managed array and copy the data into it. This assumes that the unmanaged API has a size parameter (which it invariably does) that indicates the length of the unmanaged array. Here’s some example code that shows how this is done:

C++ code

typedef long (CALLBACK * READDATA)(unsigned char * data, int length);

extern "C" __declspec(dllexport)  void __stdcall SomeFunc(READDATA rd)
{
 unsigned char data[5] = {'a', 'b', 'c', 'd', 'e'};
 rd(data, 5);
}

And here’s the calling code:

C# code

delegate int ReadDataDelegate(IntPtr data, int len);

[DllImport("SimpleLib.dll")]
static extern void SomeFunc(ReadDataDelegate d);

private static void CallNativeWithCallback()
{
    ReadDataDelegate newCB = new ReadDataDelegate((data, len) =>
    {
        byte[] array = new byte[len];
        Marshal.Copy(data, array, 0, len);
        foreach (byte b in array)
        {
            Console.WriteLine((char)b);
        }
        Console.WriteLine();
        return 0;
    });
    SomeFunc(newCB);
}

Read Full Post »

This article discusses an attached behavior that lets you handle the View Window’s Closed and Closing events via commands in the View-Model. It was inspired by Reed Copsey, Jr.’s Blend behavior which is up on the Expression Code Gallery. Reed’s behavior uses a neat technique that lets the View-Model handle the Closing/Closed events of the View in an MVVM friendly manner. Since his code was tied to the Expression DLLs I thought it would be a good idea to write a plain WPF version. While similar in concept to the Blend behavior, I’ve slightly deviated from how the concept is implemented and also in how it’s used. So this is not a direct 1-to-1 replacement though you should be able to get things working pretty much the same without too much effort.

Article Link

Read Full Post »

The Exif Compare Utility is a WinDiff equivalent for image files that compares the Exif meta-data and displays the differences and similarities. The application is written using WPF and MVVM, and also makes use of my ExifReader library. In the article I briefly explain how to use the application and also discuss some of the interesting code implementation details.

Article Link:

Read Full Post »

The majority of MFC apps have always had an About… menu entry in the main window’s system menu, and this was primarily because the App Wizard generated code for that by default. I wanted to do something similar in a WPF application I’ve been working on, and I wanted to do it in an MVVM friendly manner. In this recent article published on The Code Project, I explain a neat way of doing it so that you can easily add menu items and attach command handlers to them while retaining the basic MVVM paradigm. The code supports command parameters as well as an UI enabling/disabling mechanism. The basic idea is to make it so that it should be very easy to add system menu-items and then bind commands to them without having to make major changes to code.

I was rather cynical about all the buzz around MVVM, but now that I’ve begun using it I can see why so many people are fascinated by the concept.

Read Full Post »

Update – Apr 9, 2010

You do not need to do all this – instead you just need to set UpdateSourceTrigger on the Binding to PropertyChanged. I’ve made an updated blog entry on this here : Correction for the instant binding attached behavior for WPF TextBoxes

Original entry follows for posterity

The default behavior for a TextBox is to invoke data binding when the TextBox loses focus. Normally this is fine since people do have to hit an OK button somewhere, but there are times when you’d prefer that databinding occurs as you type into the TextBox. I wrote an attached property for the TextBox which invokes data binding as you type into it, and not when the text box goes out of focus. Here’s how you would use it.

<TextBox Height="23"
  nsmvvm:TextInstantBindingBehavior.EnableInstantBinding="True"
  Text="{Binding EnteredName}" HorizontalAlignment="Left"
  Margin="144,64,0,0" Name="textBoxName"
  VerticalAlignment="Top" Width="152" />

Here’s the code for the attached property.

public class TextInstantBindingBehavior
{
    public static DependencyProperty EnableInstantBindingProperty =
      DependencyProperty.RegisterAttached(
          "EnableInstantBinding",
          typeof(bool), typeof(TextInstantBindingBehavior),
          new FrameworkPropertyMetadata(
              new PropertyChangedCallback(EnableInstantBindingChanged)));

    public static void SetEnableInstantBinding(TextBox target, bool value)
    {
        target.SetValue(
          TextInstantBindingBehavior.EnableInstantBindingProperty, value);
    }

    public static bool GetEnableInstantBinding(TextBox target)
    {
        return (bool)target.GetValue(EnableInstantBindingProperty);
    }

    private static void EnableInstantBindingChanged(
        DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        TextBox element = target as TextBox;

        if (element != null)
        {
            if (e.NewValue != null && (bool)e.NewValue)
            {
                element.TextChanged += Element_TextChanged;
            }
            else
            {
                element.TextChanged -= Element_TextChanged;
            }
        }
    }

    static void Element_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox textBox = (TextBox)sender;

        if (GetEnableInstantBinding(textBox))
        {
            BindingExpression bindingExpression =
              textBox.GetBindingExpression(TextBox.TextProperty);

            if (bindingExpression != null)
            {
                bindingExpression.UpdateSource();
            }
        }
    }
}

Read Full Post »

Older Posts »

Follow

Get every new post delivered to your Inbox.