I have a number of classes that reflect tables in a database. I would like to have a base class that has some basic functionality (say, it would have a "isDirty" flag), and a static array of strings with the column names as they appear in the database. The following code doesn't work but illustrates what I would like to do:
public class BaseRecord {
public bool isDirty;
public object [] itemArray;
public static string [] columnNames;
}
public class PeopleRec : BaseRecord {
}
public class OrderRec : BaseRecord {
}
public static void Main() {
PeopleRec.columnNames = new string[2];
PeopleRec.columnNames[0]="FIRST_NAME";
PeopleRec.columnNames[1]="LAST_NAME";
OrderRec.columnNames = new string[4];
OrderRec.columnNames[0] = "ORDER_ID";
OrderRec.columnNames[1] = "LINE";
OrderRec.columnNames[2] = "PART_NO";
OrderRec.columnNames[3] = "QTY";
}
public class DoWork<T> where T : BaseRecord {
public void DisplayColumnNames() {
foreach(string s in T.columnNames)
Console.Write("{0}", s);
}
public void DisplayItem(T t) {
for (int i=0; i<itemValues.Length; i++) {
Console.Write("{0}: {1}",t.columnNames[i],t.itemValues[i])
}
}
}
I would like each derived class to have it's own static array of strings of database column names, and I would like the generic class to access this static member without the need for an instance.
But it doesn't work:
(A) columnNames is the identical array in BaseRec, PeopleRec and OrderRec. I cannot have columnNames be different. BaseRec.columnNames.Length would be 3 because the columnNames in OrderRec is initialized last.
(B) The notation T.columnNames does not compile.
Any ideas on how to fix this?
Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.
Quick A: Yes, and there are no ambiguity with static members.
Static members cannot be inherited because they belong to the class declaring them (because they are actually just global variables with some more advanced access), but your derived class can still access them without having to write Base:: (of course they have to be atleast protected ).
When the member variables are declared with a static keyword in a class, then it is known as static member variables. They can be accessed by all the instances of a class, not with a specific instance. The member function of a class declared with a static keyword is known as a static method.
The issue is you that you want to associate some data with the types, not with instances of the types. I'm not sure that there's a neat way of doing this in C#, but one possibility is using a static Dictionary<Type, string[]>
on BaseRecord
. An example is below, you could neaten this up by adding some generic static members on BaseRecord
for initializing/accessing the record names (and add some error checking...):
using System;
using System.Collections.Generic;
namespace Records
{
public class BaseRecord
{
public bool isDirty;
public object[] itemArray;
public static Dictionary<Type, string[]> columnNames = new Dictionary<Type, string[]>();
}
public class PeopleRec : BaseRecord
{
static PeopleRec()
{
string[] names = new string[2];
names[0] = "FIRST_NAME";
names[1] = "LAST_NAME";
BaseRecord.columnNames[typeof(PeopleRec)] = names;
}
}
public class DoWork<T> where T : BaseRecord
{
public void DisplayColumnNames()
{
foreach (string s in BaseRecord.columnNames[typeof(T)])
Console.WriteLine("{0}", s);
}
public void DisplayItem(T t)
{
for (int i = 0; i < t.itemArray.Length; i++)
{
Console.WriteLine("{0}: {1}", BaseRecord.columnNames[typeof(T)][i], t.itemArray[i]);
}
}
}
class Program
{
public static void Main()
{
PeopleRec p = new PeopleRec
{
itemArray = new object[] { "Joe", "Random" }
};
DoWork<PeopleRec> w = new DoWork<PeopleRec>();
w.DisplayColumnNames();
w.DisplayItem(p);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With