簡體   English   中英

在 c# 中實現 BaseEntity class

[英]Implementing BaseEntity class in c#

我正在嘗試在 c# 中實現BaseEntity class,我發現了這樣的示例:

 public abstract class BaseEntity<T> : IBaseEntity<T>
 {
    public T Id { get; set; }
    object IBaseEntity.Id
    {
       get { return Id; }
    }
    public bool IsValid { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime ModifiedDate { get; set; }
 }

我想知道為什么這個例子繼承自 Interface IBaseEntity ,這真的需要嗎?

這段代碼實際上做了什么?

object IBaseEntity.Id
{
    get { return Id; }
}

這些東西真的讓我很困惑..

這不能簡單地寫成這樣:

public abstract class BaseEntity<T> 
{
    public T Id { get; set; } // I guess this "T" means that this id might be of different type? like long, guid, int?

    public bool IsValid { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime ModifiedDate { get; set; }
}

我想它可以像最后一個例子那樣寫,但我猜第一個例子更有用? 但我不知道為什么,因為我真的是初學者。

如果有人可以向我解釋,我會非常感激!

提前致謝!

這段代碼究竟做了什么?

這稱為顯式接口實現: https : //docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation

通過這樣做,方法/屬性只能通過接口類型訪問,而不是通過類類型。

難道這不能簡單地寫成這樣:

是和否。 這取決於需求。 在這種情況下,我會說答案是否定的,因為界面上的Id是只讀的。 看來作者是故意弄成這樣的,只能通過接口讀不能寫,類型只知道接口。

它在類上變得可寫是類的行為,我猜,使Id易於設置。

但是,如果Id可以讀寫,則可能不使用該接口。

你錯過了接口的定義,我認為它是這樣的;

IBaseEntity{
    object Id { get; }
}
IBaseEntity<T>:IBaseEntity{
    T Id { get; set; }
}

這里解決的問題不是BaseEntity的實現,而是想要處理它們的調用者。 如果您想引用IBaseEntity<T>的實例,您的代碼將需要知道T是什么類型。 強迫您向每個類/方法或大量反射添加通用覆蓋。 但是,如果您使用底層IBaseEntity接口,則可以避免這種情況。 例如;

    Dictionary<object, IBaseEntity> entities = ...;
    entities[e.Id] = e;

我認為對基本實體 class 使用接口會導致不必要的代碼重復。 而是使用摘要 Class。可能類似於以下內容:

namespace Domain;
public abstract class BaseEntity
{
    public long Id { get; private set; }

    public override bool Equals(object? obj)
    {
        var other = obj as BaseEntity;

        if (ReferenceEquals(other, null))
        {
            return false;
        }

        if (ReferenceEquals(this, other))
        {
            return true;
        }

        if (GetType() != other.GetType())
            return false;

        if (Id == 0 || other.Id == 0)
            return false;

        return Id == other.Id;
    }

    public static bool operator ==(BaseEntity a, BaseEntity b)
    {
        if (ReferenceEquals(a, null) && ReferenceEquals(b, null))
        {
            return true;
        }

        if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
        {
            return false;
        }

        return a.Equals(b);
    }

    public static bool operator !=(BaseEntity a, BaseEntity b)
    {
        return !(a == b);
    }

    public override int GetHashCode()
    {
        return (GetType().ToString() + Id).GetHashCode();
    }
}

由於三種類型的平等,我使用這個解決方案。

  • 標識符相等
  • 參考平等
  • 結構平等

標識符相等意味着兩個對象相等當且僅當它們具有相同的標識,如 Id。 引用相等意味着兩個對象相等當且僅當它們在 memory 中占據相同的位置結構相等意味着兩個對象相等當且僅當它們是值同構的,即每個對象的字段相等。

實體往往表現出標識符和引用平等。 因此,只有使用抽象 class 才有意義。值對象傾向於展示 Refere

還要記住,值對象可能也需要它們自己的基數 class。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM