Posts in category .net - page 28

IEnumerable as IEnumerable

A few weeks ago I touched on the substitutability of generic types and how Collection<BaseClass> is never substitutable for Collection<SubClass>. This is because while the read facilities would be substitutable the write ones would not be. A Collection can’t contain non-SubClass classes.

One approach for dealing with collections in general recommended in .NET Framework Design Guidelines is to expose IEnumerator or IEnumerable interfaces rather than the collection itself – especially if you intend on it being read-only.

But even IEnumerator<T> and IEnumerable<T> can’t help you if you need to return not but a base-class or interface that should be substitutable for. Unless the base-class you want _is object_ in which case seeing `IEnumerable` inherits from the non-generic `IEnumerable` solves your problem.

C#’s generics aren’t clever enough to realize that an instantiated generic class might be substitutable for another generic class although. Wilco points out that the .NET CLR supports “generic contravariance” but C# doesn’t yet expose it.

In the mean time trying to passing back IEnumerator<T> to something expecting IEnumerator<BaseClassOfT> will result in a compiler error. Try cast ing it and a run-time error awaits.

One option would be to create a whole new Collection<BaseClass> and copy each SubClass element into it but this is hardly efficient or elegant.

What would be really cool is if you could somehow wrap it like;

public IEnumerable<BaseClass> BaseClasses {
    return new BaseEnumerable<BaseClass, SubClass>(subClassCollection);
}

Of course you’d need BaseEnumerator and BaseEnumerable generic classes to do this and preferably they’d be able to enforce that SubClass is of BaseClass at compile time.

So here are two classes to do just that for your enumerable pleasure.

using System;
using System.Collections;
using System.Collections.Generic;

public class BaseEnumerable<TBase, TSub> : IEnumerable<TBase> where TSub : TBase {
    private IEnumerable<TSub> subEnumerable;

    public BaseEnumerable(IEnumerable<TSub> subEnumerable) {
        this.subEnumerable = subEnumerable;
    }

    public IEnumerator<TBase> GetEnumerator() {
        return new BaseEnumerator<TBase, TSub>(subEnumerable);
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return subEnumerable.GetEnumerator();
    }
}

public class BaseEnumerator<TBase, TSub> : IEnumerable<TBase> where TSub : TBase {
    private IEnumerator<TSub> subEnumerator;

    public BaseEnumerator(IEnumerable<TSub> subEnumerable) {
        subEnumerator = subEnumerable.GetEnumerator();
    }

    public BaseEnumerator(IEnumerable<TSub> subEnumerator) {
        this.subEnumerator = subEnumerator;
    }

    public TBase Current {
        get { return subEnumerator.Current; }
    }

    public bool MoveNext() {
        return subEnumerator.MoveNext();
    }

    public void Reset() {
        subEnumerator.Reset();
    }
}

They work clean and fast for me but I’m no expert on the responsibilities of implementing the Dispose pattern. Warranty is not included and your mileage may vary.

[)amien

Piecing together Microsoft’s XNA gaming platform

I’ve briefly covered Microsoft’s XNA gaming platform before but have been trying to piece together what it is actually going to mean to developers.

Major update!</p>

Sorry, had to clarify the whole commercial/non-commercial parts. XNA Framework is just a portion of XNA… that won’t apply to the big guys.

Homebrew/public

Microsoft have made it clear they want to open up XNA to interested parties which should mean home-brew software.

These guys will be using C# in conjunction with XNA Build, XNA Studio, XNA Framework and managed libraries.

Licensed developers

Licensed 360 developers get a whole set of tools and technologies that are under tight NDA just like those Sony and Nintendo insist on for their licensed developers.

These guys will be using C++ in conjunction with XNA Build, XNA Studio and no doubt 360-optimized unmanaged libraries based on Direct3D, Xinput and XACL.

Whether XNA lets Microsoft get the 360 and Windows XNA gaming platforms a little closer is anyone’s guess. Being under NDA I doubt the general public would even know.

Language

C# for home-brew developers, C++ for licensed studios.

There’s no way the licensed studio’s are going to change and C# lets the new guys get up to speed quicker.

Licensed studios will have full control, full speed and continue to use their existing libraries and middle-ware.

Core framework – .NET 2.0 BCL

.NET 2.0 Base Class Library – well a modified version of it for those using the XNA Framework and C#.

Seeing as C# is the only managed language on the menu and games are rather performance sensitive expect CLS compliance to disappear and plenty of under-the-hood optimizations now that they don’t have to support other languages.

Graphics framework – MDX2

The graphics framework is based on the graphic assemblies of Managed Direct X 2.0 (MDX2) which currently ships as part of the DirectX SDK.

MDX2 is currently beta and will never hit a final release now all attention is now focused on the “XNA Graphics API” version that will see the weight drop and aim to be more cross-platform – no doubt hiding away all the platform-specific optimizations inside the libraries themselves.

There will be no System.Drawing and no System.Windows.Form name spaces so forget about them.

Audio framework – XACT

Microsoft Cross-Platform Audio Creation Tool (XACT). Grab it from the latest DirectX SDK and forget about DirectSound and DirectMusic. They won’t make it.

Input framework – Xinput

XInput kicks DirectInput off the scene with it’s easier-to-use API and support for vibration and varied controller types and voice headset.

Grab the XInput Driver for Microsoft Common Controller, plug in the 360 controller on your PC and start messing round.

Build tools – XNA Build

XNA Build is based on MS Build but adds asset (textures, samples, music etc) tracking to the mix to ensure you don’t do like Microsoft and ship almost an entire CD’s worth of unknowingly unused assets with your Mech Commander. It also lists incremental and distributed builds on the feature list.

A March 2006 technology preview is available that integrates with Visual Studio 2005.

IDE – XNA Studio

Once again Microsoft takes from it’s existing .NET tool-set and makes an XNA version – in this case Visual Studio 2005 Team System..

Whether the cheaper home-brew/XNA Framework/C# version will have all the C++ features stripped is anyone’s guess.

Live Anywhere!

Microsoft have already announced their plan to take online gaming from the Xbox 360 (gamertags, achievements, friends, chat) and make it cross-platform across to Windows and mobile gaming.

It would make of sense then that the Live Anywhere! system is .NET framework for use with XNA – even if it doesn’t officially make up part of the package.

Have to sit and wait for this one to pan out.

Platforms

Microsoft will be supporting:

  • Xbox 360
  • Windows XP 32-bit/64-bit*
  • Windows Vista 32-bit/64-bit*

Mac OS X?

Apple should really be negotiating to get XNA on Mac OS X. It already internally supports PowerPC (360, G3, G4, G5) and Intel (Windows, IntelMac) as what they offer developers seems rather weak – about the only reusable element is OpenGL.

This would allow existing XNA games to be ported with ease although would be of little use to existing Apple developers who use Objective-C/C++ and wouldn’t want to interop with C#.

Linux?

Linux already has Mono & DotGnu which could provide the basis for a .NET based gaming platform but I can’t see Microsoft wanting to open up the source for a successful Linux port.

The only obvious route here would be for Linux developers to either implement it themselves or wrap around existing technologies – Wine/OpenGL etc.

Sources & info

[)amien

Substitutability of generic types in .NET

The “is” operator

Anyone using object orientated programming soon finds themselves wanting to perform some action only if an object is of some type or implements some interface.

The easiest way is to do this is to use the “is” operator. Typically it will appear something like;

object objA = FunctionToGetAnObject();
if (obj is SomeClassOrInterface)
    ((SomeClassOrInterface) obj).SomeMethod();

Here if obj_A is of a type that implements SomeClassOrInterface anywhere in its inheritence tree then SomeMethod of SomeClassOrInterface will be called.

Test substitution with generic types

Now lets say we have our own generic type – here’s one to illustrate a point;

public class DamoClass<T> {
    public T GetProperty { get { ... } }
    public T SetProperty { set { ... } }
    public bool IsValid { return true; }
}

If we want to check obj_A supports DamoClass<T> but we don’t care what type T is you might expect to be able to perform;

if (objA is DamoClass)

But that results in a compilation error – you can’t reference a generic class without specifying the type parameters regardless of whether you care about them or not. You might then try;

if (objA is DamoClass<object>)

After all every class inherits from object. This compiles fine but at runtime if objA is of any type other than object, e.g. DamoClass<string> it will return false.

Why?

The following might be what you had in mind;

if (objA is DamoClass<object>) {
    ((DamoClass<object>) objA).IsValid();
    object test = ((DamoClass<object>) objA).GetProperty;
}

Which looks fine but if .NET allowed that then how would it prevent;

if (objA is DamoClass<object>)
    ((DamoClass<object>) objA).SetProperty = 11;

When objA.AssociatedObject might well be something other than an integer? It can’t – so it doesn’t.

Solution

The solution is to split your generic class into two classes.

The first contains your non-generic methods and properties and the second inherits from the first adding all the generic specialisation. The good news is that they can even have the same name.

public class DamoClass {
    public object GetProperty { get { ... } }
    public bool IsValid { return true; }
}

public class DamoClass<T> : DamoClass {
    public T SetProperty { set { ... } }
}

Then you are free to do;

if (objA is DamoClass) {
    ((DamoClass) objA).IsValid();
    object test = ((DamoClass) objA).GetProperty;
}

Indeed .NET itself uses this technique for IEnumerable and IEnumerable

One drawback with this technique is that you can’t redefine the type of a member in the subclass – maybe that’ll make C# 3.0.

[)amien

Handling nullable value types in .NET 1.x

One of the great new features in .NET 2.0 is support for nullable types – especially important when dealing with value types such as Int or DateTime values coming from a database. Previously you were forced to either set and track another binary flag or to use a “special” value to represent null that sooner or later would turn up in real data.

In C# 2.0 thanks to a bit of syntactic sugar we can do this;

int? nullable1 = 1;
if (nullable1 == null) nullable1 = 2;

Which the C# compiler actually turns into the following:

Nullable<int> nullable1 = new Nullable<int>(1);
if (!nullable1.HasValue) nullable1 = new Nullable<int>(2);

This makes use of the new Nullable generic structure to wrap the value with an additional boolean HasValue property.

That looks surprisingly similar to the syntax of the open-source NullableTypes project you can use with .NET 1.1 (or 2.0):

NullableInt32 nullable1 = new NullableInt32(1);
if (nullable1.IsNull) nullable1 = new NullableInt(2);

Disclaimer: I’ve worked on the NullableTypes project specifically implementing the IXmlSerializable, NullableGuid & NullableTimeSpan.

[)amien