1

I have a class that serves as a wrapper for a specific table within a database. Within the constructor of this class (let´s call it MyLookup) we make some initialization (e.g. reading some metadata). Now I am supposed to create a second table within the database which is more or less a copy of the first.

class MyLookup {
    public const TABLE_NAME = "MYTABLE";
    private readonly ITable table;

    MyLookup() { 
        this.table = OpenTable(TABLE_NAME); 
        /* further init */
    }
}

The problem is that the code for initialization is more or less the same as of the "base"-table. only difference is its actual name. Usually I´d just change the constant TABLE_NAME to become a virtual property that can be overridden within my derived table-class. But that const may be used within legacy code hence changing it to a property would lead to also changing its access (instance instead of static). So how may I call the base-initialization with a different TABLE_NAME by only making least changes to MyLookup?

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • As part of this could you not change the legacy code too? – Belogix Mar 16 '15 at 10:47
  • @Belogix No, its customer code unfortunately. – MakePeaceGreatAgain Mar 16 '15 at 10:48
  • 1
    Is the TABLE_NAME const really a private constant ? I think you're on right track with overridden property - just name it differently (the property) and let the TABLE_NAME live as it is with [Obsolete] attribute. – Ondrej Svejdar Mar 16 '15 at 10:50
  • I'm not totally sure but as far as I know if you have some const, the compiler will not make an variable but instead pass the exact value each time the const is used. This happens at compile time. So if you make your changes, this wont break the existing code (but it will be much harder to debug in future). – Andre Mar 16 '15 at 10:51
  • @OndrejSvejdar I already thought on marking the const obsolete. Might be the way going. – MakePeaceGreatAgain Mar 16 '15 at 10:51
  • @Andre I think changing it to property will change the access from static (const) to instance. Thus whilst the following worked until now, it would not when accessing as property: `MyLookup.TableName`. This leads to compiler-error when `TableName` is a property. – MakePeaceGreatAgain Mar 16 '15 at 10:57

1 Answers1

1

After all the comments, here is (hopefully) zero-conflict approach:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class TableNameAttribute : Attribute
{
  public string TableName { get; set; }
}

public class BaseLookup<TSelfReferenceType>
{
  public static string TABLE_NAME
  {
    get 
    { 
      var attributes = typeof(TSelfReferenceType).GetCustomAttributes(typeof(TableNameAttribute), false); 
      if (attributes == null || attributes.Length == 0)
      {
        return null;
      }
      return ((TableNameAttribute)attributes[0]).TableName;
    }
  }
}

[TableName(TableName = "MyLookup")]
public class MyLookup : BaseLookup<MyLookup>
{
}

[TableName(TableName = "ChildLookup")]
public class ChildLookup : BaseLookup<ChildLookup>
{
}

// write out MyLookup
Console.Out.WriteLine(MyLookup.TABLE_NAME);
// write out ChildLookup
Console.Out.WriteLine(ChildLookup.TABLE_NAME);
Ondrej Svejdar
  • 21,349
  • 5
  • 54
  • 89
  • Wow, looks bit strange but it works however. What I don´t get is why this kind of inheritance with a static member works. – MakePeaceGreatAgain Mar 16 '15 at 12:40
  • @HimBromBeere - its actually not a static inheritance; its just abuse of generics :) – Ondrej Svejdar Mar 16 '15 at 12:42
  • As far as I read from here http://stackoverflow.com/questions/2281775/c-sharp-static-member-inheritance-why-does-this-exist-at-all it actually HAS to do with inheritance, although it´s a misleading term within this context. The `ChildLookup`-class does not have any `TableName`-member, it "inherits" it from `BaseLookup`. Even without generics your code would compile. – MakePeaceGreatAgain Mar 16 '15 at 12:57