5

I've just read a post about Generic Entity Base Classes. Simply and if I'm not wrong, the main idea in behind is collecting all generic, non-entity-spesific fields in one interface, than implement it in main entities. It's going to be a TL:DR; Let's see some code.

This is the base entity interface and it's generic impementation to another interface

public interface IEntity : IModifiableEntity
{
    object Id { get; set; }
    DateTime CreatedDate { get; set; }
    DateTime? ModifiedDate { get; set; }
    string CreatedBy { get; set; }
    string ModifiedBy { get; set; }
    byte[] Version { get; set; }
}

public interface IEntity<T> : IEntity
{
    new T Id { get; set; }
}

And this is it's implementation into an abstract class

public abstract class Entity<T> : IEntity<T>
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public T Id { get; set; }
    object IEntity.Id
    {
        get { return this.Id; }
    }

    public string Name { get; set; }

    private DateTime? createdDate;
    [DataType(DataType.DateTime)]
    public DateTime CreatedDate
    {
        get { return createdDate ?? DateTime.UtcNow; }
        set { createdDate = value; }
    }

    [DataType(DataType.DateTime)]
    public DateTime? ModifiedDate { get; set; }

    public string CreatedBy { get; set; }

    public string ModifiedBy { get; set; }

    [Timestamp]
    public byte[] Version { get; set; }
}

It seems perfectly clear and understandable but one point about Id's. My question is(yeah, finally)

  • Why do we have two different Id property in both IEntity and IEntity interfaces?

  • What does the new keyword doing there? What's going on? :O

Uğur Cem Öztürk
  • 330
  • 1
  • 3
  • 14
  • 1
    Because one is from the non-generics interface, which is just of type `object`, and the other one is of the specific type `T`. You need to use `new` because it's of a different type and you want to overwrite the inherited declaration. `Entity` also explicitly implements the non-generics `Id` in case the instance is accessed via that interface. – Andrew May 02 '18 at 14:01
  • But all concrete entities derived from Entity abstract class and uses the generic ID property to generate one. So the object Id is redundant, isn't it? – Uğur Cem Öztürk May 02 '18 at 14:04
  • 3
    You won't use `object Id` if you are using `IEntity`. You could, but there's probably no point in doing so. – Andrew May 02 '18 at 15:56

1 Answers1

4

Why do we have two different Id property in both IEntity and IEntity<T> interfaces?

IEntity<T> derives from IEntity, but allows you to pass a specific type that you want your Id property to be. The base interface definition IEntity has the Id property define as an object, which is not type safe and, if used in Entity Framework, would not translate to a database friendly data type.

What does the new keyword doing there? What's going on? :O

The new keyword of the property definition makes the code easier to read and understand. Since IEntity<T> has a property named Id defined that is hiding the base implementation IEntity.Id. The "new" keyword makes it easier to understand that IEntity<T>.Id hides the base implementation of IEntity.Id

A bit further

In your derived classes of the base abstract class of Entity you would be providing the type of the ID property like so:

public class DerivedEntity : Entity<int>
{
    public string AnotherProperty { get; set; }
}   

This tells the compiler that the Id property is of type "int" through the type parameter "T" of Entity<T> making easier to use and understand what the Id property is supposed to be in your derived classes.

bman7716
  • 693
  • 7
  • 14
  • 1
    Just for reference, here is Microsoft's definition of the "new" keyword. All the "new" keyword does is makes the hiding of the base implementation explicit and not implicit. The compiler will assume you knew what you were doing when you hid the base version of the property or method and will take the derived class version over the base implementation. [link](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier) – bman7716 May 02 '18 at 14:30