Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Currently I am porting piece of code from some old Delphi API to C# and smashed into weirdness of type definitions. As its schema fits perfectly with DLL it uses (because it also was made in Delphi and keeps its style) I decided to cover for differences with some generic magic.

Technological constraints forced me to use .NET 2.0 (You expected such API to run on modern system?)

In Delphi (also known is some underground communities as Object Pascal) it is possible to create abominable typed arrays:

TFoo = Array[0..8] of Byte;
TEnum = (rawr, roar, gnar);
TBar = Array[TEnum] of Word;

In said API such little zerglings define most of data and are passed wildly around by pointers so object mimicking array (reference type is good enough) was required:

public class TArray<T>
{
    internal T[] internalArray;

    public TArray(int size)
    {
        internalArray = new T[size];
    }

    public TArray(T[] array)
    {
        internalArray = array;
    }

    public T this[int i]
    {
        get { return internalArray[i]; }
        set { internalArray[i] = value; }
    }

    public static implicit operator T[](TArray<T> tab)
    {
        return tab.internalArray;
    }

    public T[] Array
    {
        get
        {
            return internalArray;
        }
    }
}

And similar monstrosity for arrays indexed by enums (In more civilized days we would use some Dictionary, but since fire nation attacked everything paper became scarce)

public class TEnumArray<T, E> : TArray<T> where E : struct, IConvertible
{
    public TEnumArray()
        : base(Enum.GetValues(typeof(E)).Length)
    {
    }

    public TEnumArray(T[] array)
        : base(array)
    {
    }

    public T this[E i]
    {
        get { return internalArray[(int)(object)i]; }
        set { internalArray[(int)(object)i] = value; }
    }

    public static implicit operator T[](TEnumArray<T, E> tab)
    {
        return tab.internalArray;
    }
}

Usage is quite simple

public class TFoo:TArray<byte>
{
    public TFoo()
        : base(123)
    {
    }
}
public enum TEnum = {rawr=0, roar, gnar};
public class TBar:TEnumArray<ushort, TEnum>
{
    public TBar()
        : base()
    {
    }
}

To mimic pure array I added no exception handling on indexers.

Can it be made cleaner/better/faster? Is there some obscure Delphi functionality I am missing?

share|improve this question
    
I'm a bit confused about what TArray<T> is for. Where would you use a TArray<T> that a T[] wouldn't be sufficient? –  Ben Aaronson May 15 at 15:25
    
@BenAaronson It is helper for 1-to-1 translation and it adds some bounds protection as class can control underlying array size (and provide some data-parsing logic). Code I am translating is full of various "typed arrays", used as out (ref) arguments in functions to which external DLL writes results. In modern world those would be real objects. It gives me extendable array container. There is dozen or so various "typed arrays" in code and now they are all hidden away from possibility of incorrect size (Access Violation! The horror!) –  PTwr May 15 at 23:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.