4

I have the following base and derived (partial, for sake of brevity) classes:

class Base {
     public abstract int[] someArray { get; }
}

class Derived : Base {
     private readonly static int[] _someArray = new int[] { 1,2,3,4 };
     public override int[] someArray { 
         get {
              return _someArray;
         }
     }
}

What I would like now, is put the new int[] { 1,2,3,4 } in the return part of the getter. But, that would create a new array every time the getter is called.

Is it possible to directly return some kind of object, which stays the same for all objects of class Derived ?

Something along the lines of (I know this is invalid C#):

  get {
        return (int[]) { 1, 2, 3, 4 };
  }
6
  • 3
    What's the problem in using the field? Commented Dec 14, 2012 at 10:37
  • 1
    Can I confirm: do you want the same instance each time? or do you want a different instance each time? Commented Dec 14, 2012 at 10:38
  • 1
    @TimSchmelter the main reason is to have as little as possible double code. There are many Deriveds from one Base, and they all have a class-wide array. To be precise: the array holds a list of supported features which can vary per Derived. Commented Dec 14, 2012 at 10:39
  • 1
    So... you just don't like having the static field / initializer visible? if so: why? the code you have is direct, working, and obvious: there are good things in code Commented Dec 14, 2012 at 10:48
  • 1
    @MarcGravell I agree. I am just always trying to code in such a way that it stays maintainable and shorten's programmer time. Also, these kind of things help me learn to get to know C# better. Commented Dec 14, 2012 at 10:56

2 Answers 2

4

If you only want to put the new int[] { 1,2,3,4 } part into the getter, that's easy...

 private static int[] _someArray = null;
 public override int[] someArray { 
     get {
          return _someArray ?? (_someArray = new int[] { 1,2,3,4 });
     }
 }

You'd lose the readonly then, though.

UPDATE: Generics solution

Or you could abuse the features of generics for that:

// Of course you still want to use the non-generic class Base
abstract class Base {
    public abstract int[] someArray { get; }
}

abstract class Base<T> : Base where T: Base<T> {
     // Will be created once for every T, i.e. every derived class.
     private static int[] _someArray;

     public override int[] someArray {
        get { return _someArray ?? (_someArray = CreateArray()); }
     }

     protected abstract int[] CreateArray();
}

sealed class Derived : Base<Derived> {
     protected sealed override int[] CreateArray() { 
         return new int[] { 1,2,3,4 };
     }
}

sealed class DerivedB : Base<DerivedB> {
    protected sealed override int[] CreateArray() {
        return new int[] { 2,3,4,5 };
    }
}

Note that this only works for one inheritance level, so i sealed some stuff :)

Sign up to request clarification or add additional context in comments.

14 Comments

This could work. If I also put the _someArray field in the base class, my derived classes all have just one getter.
He don't want to use a field at all.
@BartFriederichs You can't put _someArray into the base class, because then you wouldn't have one array per derived class but just one from the base class. If you want something static to each derived class, you won't get around declaring it in the derived class.
@TimSchmelter, using a field is not the main issue here. The main issue is code re-use.
@TimSchmelter He didn't explicitly state that.
|
0

As far as i know that will not work in C#. You can either use a field or create a variable in the property/method. In VB.NET you have the Static keyword for local variables(see below).

You have commented that you have many derived classes and you don't want to have a static field array for each derived class. I would suggest to use a different approach then. You could f.e. use a static Dictionary in your base class and an enum for each derived class:

abstract class Base
{
    public abstract DerivedType Type { get; }

    protected static readonly Dictionary<DerivedType, int[]> SomeDict;

    static Base()
    {
        SomeDict = new Dictionary<DerivedType, int[]>();
        SomeDict.Add(DerivedType.Type1, new int[] { 1, 2, 3, 4 });
        SomeDict.Add(DerivedType.Type2, new int[] { 4, 3, 2, 1 });
        SomeDict.Add(DerivedType.Type3, new int[] { 5, 6, 7 });
        // ...
    }

    public static int[] SomeArray(DerivedType type)
    {
        return SomeDict[type];
    }
}

public enum DerivedType
{
    Type1, Type2, Type3, Type4, Type5
}

class Derived : Base
{
    public override DerivedType Type
    {
        get { return DerivedType.Type1; }
    }
}

In VB.NET, however, it is possible using a static local variable using the Static-keyword:

MustInherit Class Base
    Public MustOverride ReadOnly Property someArray() As Integer()
End Class

Class Derived
    Inherits Base
    Public Overrides ReadOnly Property someArray() As Integer()
        Get
            Static _someArray As Int32() = New Integer() {1, 2, 3, 4}
            Return _someArray
        End Get
    End Property
End Class

_someArray will be the same for every instance of Derived.

1 Comment

Yes, that would have been my first solution, but C# doesn't support that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.