简体   繁体   中英

C# as operator on Type with generics but irrelevant <T>

I have an abstract base class with generics, I will simplify it for this question:

public abstract class DBBaseTable<T>
{
    public T Id { get; set; }     
    public byte[] RowVersion { get; set; }
}

Now, I can have classes like: Person : DBBaseTable<int> or Animal: DBBaseTable<Guid>

I am trying to avoid reflection in order to access the property RowVersion in a part of the code where I simply do not know the T Type.

var memberInfo = oldObject.GetType().BaseType;
if (memberInfo != null 
    && memberInfo.IsGenericType
    && memberInfo.GetGenericTypeDefinition() == typeof(DBBaseTable<>)
)
{   
    var isCorrectRowVersion = (oldObject as DBBaseTable<object>).RowVersion ==
                              (objToUpdate as DBBaseTable<object>).RowVersion;

    //TODO....  
}

The conditional IF condition is working fine... but then when I try to use the as operator I always need to specify the T type... I have tried to use "object" but it is not working... and I simply do not know if I am dealing with int, guid or some other type....

I know how to solve this with reflection, but I would like to know if there is an alternative?

Move the RowVersion into a base class.

public abstract DBBaseTable
{
    public byte[] RowVersion { get; set; }
}

public abstract class DBBaseTable<T> : DBBaseTable
{
    public T Id { get; set; }     
}

Another option is to declare a base interface with RowVersion property and implement it in DBBaseTable<T> base class

public interface IDBTable
{
    byte[] RowVersion { get; set; }
}

public abstract class DBBaseTable<T> : IDBTable
{
    public T Id { get; set; }
    public byte[] RowVersion { get; set; }
}

public class Person : DBBaseTable<int>
{
    //rest of logic
}

Then you can access a RowVersion property without a cast

var isCorrectRowVersion = oldObject.RowVersion == objToUpdate.RowVersion;

With interfaces you are allowed to use covariance and contravariance in generic types.

Also, you can implement multiple interfaces in one class, but inherit only one base class in DBBaseTable<T> . If you'll need to extend it in future, using an interface is preferable, IMO. But final decision depends on your needs.

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