Of all the meth­ods avail­able on the Enu­mer­able class, OfType<T> is arguably one of the most use­ful and yet under uti­lized method.

For exam­ple, you have a list of Cat and Dog objects, all inher­it­ing from a com­mon Ani­mal class, but occa­sion­ally you want to per­form oper­a­tions on only the dogs or cats, and that’s where OfType can come in handy:

public class Animal
{
    public string Name { get; set; }
}
public class Dog : Animal {}
public class Cat : Animal {}
…

var animals = new Animal[] { new Cat { Name = "Jess" },
                             new Cat { Name = "Tad" },
                             new Dog { Name = "Bob" } };
// get the dogs from the array of animals, functional style
var dogs = animals.OfType<Dog>();

// get the cats from the array of animals, true imperative style
var cats = new List<Cat>();
foreach (var animal in animals)
{
    if (animal is Cat)
        cats.Add(animal as Cat);
}

Of course, you could equally have fil­tered the array like this:

// lambda expression syntax
var cats = animals.Where(a => a is Cat).Select(a => a as Cat);
// query expression syntax
var cats = from a in animals where a is Cat select a as Cat;

But using OfType is far cleaner and expres­sive of your intent.

Share

If you have an inter­face like this:

IDal<T>

with a con­crete class like this, which you want to wire up with Castle:

Dal : IDal<IEntity>

Then here’s the syn­tax to spec­ify the com­po­nent in your Cas­tle Wind­sor con­fig­u­ra­tion file

<component id="myDal"
           service="Namespace.IDal`1[[Namespace.IEntity, Assembly]], Assembly"
           type="Namespace.Dal, Assembly"/>

Sim­i­larly, imag­ine if you have more than one generic type parameter:

IRetrievable<T, idT>
FooRetriever : IRetrievable<Foo, string>
<component id="FooRetriever"
           service="Namespace.IRetrievable`2[[Namespace.Foo, Assembly],[System.String]], Assembly"
           type="Namespace.FooRetriever, Assembly"/>

Remem­ber, you need to use the back tick (), NOT apostrophes (‘)!

Ref­er­ences:

Stack­Over­flow ques­tion on the syn­tax to declare generic types in cas­tle config

Stack­Over­flow ques­tion on declar­ing more than one para­me­ter type in cas­tle config

Share

I ran into a ver­sion­ing prob­lem when I tried to use the lat­est ver­sion of Flu­entNHiber­nate with the lat­est ver­sion of LINQ to NHiber­nate because LINQ to NHiber­nate is built using a later ver­sion of the NHiber­nate binaries.

After doing a lit­tle search, I found a ver­sion of NHiber­nate which both LINQ to NHiber­nate and Flu­entNHiber­nate had been built against here.

So now, I can enjoy the same flu­ent inter­face to con­fig­ure NHiber­nate and the use of LINQ query like this:

var onePiece = from s in session.Linq<Series>() where s.Name == "One Piece" select s;
Share

Whilst work­ing on an image view I needed the abil­ity to bind the value of a Slider to a Scale­Trans­form as a per­cent­age value and at the same time dis­play the value of the slider in a label. So for a zoom range from 1% to 250% you would usu­ally set the Min­i­mum and Max­i­mum prop­erty of your Slider to 0.01 and 2.5 respec­tively, by then you wouldn’t be able to dis­play the zoom value as a per­cent­age, e.g. Zoom 148%.

So to get around this lim­i­ta­tion, in the end I used the range 1 to 250 for the Slider and added another Scale­Trans­form with ScaleX and Sca­leY set to 0.01, like this:

<StackPanel x:Name="LayoutRoot" Background="Gray">
    <StackPanel Orientation="Horizontal">
        <TextBlock Margin="5,5,10,5">Zoom</TextBlock>
        <TextBlock Margin="5,5,0,5" Text="{Binding Path=Value, ElementName=sldZoom, Mode=OneWay}"/>
        <TextBlock Margin="0,5">%</TextBlock>
    </StackPanel>

    <Slider x:Name="sldZoom" Orientation="Horizontal" Minimum="1" Maximum="250" Value="100"/>

    <Image Source="bingonet.png" RenderTransformOrigin="0, 0">
        <Image.RenderTransform>
            <TransformGroup>
                <ScaleTransform ScaleX="0.01" ScaleY="0.01"/>
                <ScaleTransform>
                    <ScaleTransform.ScaleX>
                        <Binding ElementName="sldZoom" Path="Value" Mode="OneWay"/>
                    </ScaleTransform.ScaleX>
                    <ScaleTransform.ScaleY>
                        <Binding ElementName="sldZoom" Path="Value" Mode="OneWay"/>
                    </ScaleTransform.ScaleY>
                </ScaleTransform>
            </TransformGroup>
        </Image.RenderTransform>
    </Image>
</StackPanel>
Share

Back in my first post on AOP, I men­tioned the Mem­o­izer on D. Patrick Caldwell’s blog, well, today I came across a sit­u­a­tion where I was able to use it but first I needed to make a few mod­i­fi­ca­tions because the orig­i­nal imple­men­ta­tion didn’t sat­isfy some of my requirements:

  • There is no cap on the size of the dic­tio­nary, I want to avoid a sit­u­a­tions where my appli­ca­tion uses too much mem­ory, and in the extreme case throws a OutOfMemoryException;
  • There is one sta­tic cache shared across all meth­ods, so even with a cap on the size of the dic­tio­nary it won’t stop one method from tak­ing up all the avail­able spaces in the dictionary
  • The order of the memos is not kept, so you won’t be able to imple­ment have FIFO strat­egy for remov­ing old memo entries

In case you’re won­der­ing why I would require these func­tion­al­i­ties, I’m build­ing an image viewer with zip sup­port and it doesn’t make sense to load all the images in the zip file into mem­ory at the start (the zip files can be typ­i­cally hun­dreds of megs big).

The images are sorted, and as you’re nav­i­gat­ing through the images it behaves like a LinkedList any­way, so I’m imple­ment­ing a slid­ing win­dow based on where you are in the list and load the pre­vi­ous and next 10 images into cache. There­fore a FIFO mem­o­izer can help reduce the amount of reads from the zip file I need to per­form (decom­pres­sion is an expen­sive operation).

And here’s the mod­i­fied ver­sion of the Mem­o­izer attribute:

[Serializable]
[AttributeUsage(AttributeTargets.Method)] // only allowed on methods
[DebuggerStepThrough]
public sealed class MemoizeAttribute : OnMethodInvocationAspect
{
    private const int DefaultMemoSize = 100; // default memo size is 100
    // private field to store memos
    private readonly Dictionary<string, object> _memos = new Dictionary<string, object>();
    // private queue to keep track of the order the memos are put in
    private readonly Queue<string> _queue = new Queue<string>();

    #region Constructors
    public MemoizeAttribute() : this(DefaultMemoSize)
    {
    }
    public MemoizeAttribute(int memoSize)
    {
        MemoSize = memoSize;
    }
    #endregion

    public int MemoSize { get; set; } // how many items to keep in the memo

    // intercept the method invocation
    public override void OnInvocation(MethodInvocationEventArgs eventArgs)
    {
        // get the arguments that were passed to the method
        var args = eventArgs.GetArgumentArray();
        var keyBuilder = new StringBuilder();
        // append the hashcode of each arg to the key
        // this limits us to value types (and strings)
        // i need a better way to do this (and preferably
        // a faster one)
        for (var i = 0; i < args.Length; i++)
            keyBuilder.Append(args[i].GetHashCode());
        var key = keyBuilder.ToString();
        // if the key doesn't exist, invoke the original method
        // passing the original arguments and store the result
        if (!_memos.ContainsKey(key))
        {
            _memos[key] = eventArgs.Method.Invoke(eventArgs.Instance, args);
            _queue.Enqueue(key);
            // if we've exceeded the set memo size, then remove the earliest entry
            if (_queue.Count > MemoSize)
            {
                var deQueueKey = _queue.Dequeue();
                _memos.Remove(deQueueKey);
            }
        }
        // return the memo
        eventArgs.ReturnValue = _memos[key];
    }
}

And here’s how you use it, remem­ber, the size cap applies to all the calls to this method (not lim­ited to a par­tic­u­lar instance):

[Memoize(5)]
private MemoryStream GetImageStream(ZipFile zipFile, string fileName)
{
    using (var memoryStream = new MemoryStream())
    {
        zipFile[fileName].Extract(memoryStream);
        return memoryStream;
    }
}
Share