简体   繁体   中英

Interface, Inheritance, and C#

I'm designing a data layer for several classes, and I want each of these classes to follow a contract I set up with IMyDataItem :

public delegate void ItemChangedHandler(object sender, EventArgs e);

public interface IMyDataItem<T> {
  string Insert { get; }
  int Save();
  string Select { get; }
  string Update { get; }
}

That being done, I now want to include a base class that my other classes all inherit from.

How would I fix this base class ?

public class MyDataItem : IMyDataItem<T> {

  private const string TODO = "TODO: This has not been done.";
  public const int NOT_SET = -1;

  private bool changed;
  internal int rowId;

  public MyDataItem() {
    changed = false;
    rowId = NOT_SET;
  }

  public ItemChangedHandler OnChange;

  internal void notify() {
    changed = true;
    if (OnChange != null) {
      OnChange(this, new EventArgs());
    }
  }

  public int RowID {
    get { return rowId; }
    set {
      if (rowId != value) {
        rowId = value;
        notify();
      }
    }
  }

  public bool SaveNeeded { get { return changed; } }

  public static virtual T Load() {
    return default(T);
  }

  public virtual string Insert { get { return TODO; } }

  public virtual string Select { get { return TODO; } }

  public virtual string Update { get { return TODO; } }

  public virtual int Save() {
    changed = false;
    return NOT_SET;
  }
}

The errors are all in the second class MyDataItem (my base class):

  • Type or namespace name 'T' could not be found - on the first line where I declare my class.

I tried removing the errors by adding a where clause to the signature:

public class MyDataItem : IMyDataItem<T> where T : MyDataItem {

However, this presented me with the error:

  • Constraints are not allowed on non-generic declarations

Is there a way to do what I am after, or will I need to stick with simpler class designs?

When the base class is complete, other classes such as Location , Employee , and Record will inherit it.

Well to fix that particularly compile time error you would need:

public class MyDataItem<T> : IMyDataItem<T>

However, without knowing more about what you're trying to achieve, it's hard to recommend an alternative approach.

Why not drop the <T> from the interface and make it non-generic? The T is not used in the interface.

Otherwise, if you want the class to be generic, say

public class MyDataItem<T> : IMyDataItem<T>

But again, if T is not used, what's your reason to declare it?

What you are attempting to do is somewhat similar to what I've also done. I've wanted some generic code applicable to all my "data manager" instances but also wanted to apply stronger typing to them... In a similar fashion...

public interface iMyDataManager
{  
   stuff ... 
}

public class MyDataManager<T> : iMyDataManager
{  
   implementation ... that I want common to all derived specific instances 
}


public class MySpecificDataInstance : MyDataManager<MySpecificDataInstance>
{
   continue with rest of actual implementations specific to this class.
}

I did not see any reason use generic in your implementation. Secondary, are you sure about parameters of these functions:

  string Insert { get; }
  int Save();
  string Select { get; }
  string Update { get; }

Why Update and Insert returns parameters? Are you sure, you will able remember meaning of this within 2 months?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM