Gaurav
Gaurav

Reputation: 8487

Issue with generics in c#

I have a problem while adding a new class in my existing structure. I am going to explain my problem as much clear as i can

public interface Imust
{
    string Name { get; set; }
    string File { get; set; }
    string RowKey { get; set; }
    string Time { get; set; }
    string PartitionKey { get; set; }
}

public class TA : TableServiceEntity, Imust
{
    public string Time { get; set; }
    public string Name { get; set; }
    public string File { get; set; }
}

public class TB : TableServiceEntity, Imust
{
    public string Time { get; set; }
    public string Name { get; set; }
    public string File { get; set; }
}

public class TC : TableServiceEntity, Imust
{
    public string Time { get; set; }
    public string Name { get; set; }
    public string File { get; set; }
}    

public class _Table <T> : _Account where T : Imust 
{
}

Here the above 3 classes are implemented as Tables and its properties as its columns in my project. Imust interface is implemented in each class because in generic class i put an interface constraint. TableServiceEntity class contains the implementation for RowKey and PartitionKey.And this class is also inherited in all 3 entities.

Problem : Now i have to add a new table in my application. So for this i have to add a new class here which is

public class TD : TableServiceEntity
{

}    

I do not want this class to implement the Imust interface because it does not contain these columns. But i have to pass it as a parameter in generic class _Table.Because this new class has different columns but it perform same function which other 3 entities does. Now how will i add this new class while maintaining my existing structur ?

Please suggest me any better solution for this problem ?

EDIT

Yes i can put a constraint TableServiceEntity as a base class. But in generic class _Table there are few function which operate on File property like

    public T AccessEntity(string Id = "0", string File = "0")
    {
        return (from e in ServiceContext.CreateQuery<T>(TableName)
                where e.RowKey == Id || e.File == File
                select e).FirstOrDefault();
    }

If i removed this interface constraint then it shows an error that T does not have a defination for File.

Upvotes: 1

Views: 152

Answers (5)

BonyT
BonyT

Reputation: 10940

Updated to reflect posters additional info:

You need to specify a new Interface:

public interface IMust2 {
    public string File {get;set;}
    public string Rowkey {get;set;

}

Modify IMust to inherit from IMust2

public interface IMust : IMust2 
{
   public string Name {get;set;}
   public string Time {get;set;}
   public string PartitoinKey {get;set;}
}

Upvotes: 0

Kuba Wyrostek
Kuba Wyrostek

Reputation: 6221

Split the interface in two:

public interface Ibase

    string RowKey { get; set; }
    string PartitionKey { get; set; }
}

public interface Imust : Ibase
{
    string Name { get; set; }
    string File { get; set; }
    string Time { get; set; }
}

public class TA : TableServiceEntity, Imust
{
    public string Time { get; set; }
    public string Name { get; set; }
    public string File { get; set; }
}

public class TB : TableServiceEntity, Imust
{
    public string Time { get; set; }
    public string Name { get; set; }
    public string File { get; set; }
}

public class TC : TableServiceEntity, Imust
{
    public string Time { get; set; }
    public string Name { get; set; }
    public string File { get; set; }
}    


public class _BaseTable <T> : _Account where T : Ibase 
{
}

public class _Table <T> : _BaseTable<T> where T : Imust 
{
}

And implement common functionality in _BaseTable and this specific to Time, Name and File in _Table.

It's even more intuitive after and edit you have made to your question. Thos methods in _BaseTable that rely on File, Name or Time can be marked abstract and overriden in _Table.

Upvotes: 1

Blau
Blau

Reputation: 5762

I'd do this... the interface has no sense in your declaration as the more generic type for table is TableServiceEntity

public class _Table <T> : _Account where T : TableServiceEntity
{
}

Upvotes: 1

Andre Calil
Andre Calil

Reputation: 7692

  1. You have 3 classes (TA, TB and TC) that are exactly the same. Why don't you have a single class, though?
  2. For behavior (that is, methods), use a interface. For structure (that is, properties), use inheritance (like at TableServiceEntity).
  3. Make TD inherit from the base class but do not implement the interface.
  4. Change the restriction at _Table to be where T : TableServiceEntity

Regards

Upvotes: 0

Josh
Josh

Reputation: 10614

Why not just have _Table be of <TableServiceEntity> type? Obviously, you are breaking your interface, so you can't keep using it as the generic as not every class will be of that interface?

Upvotes: 0

Related Questions