簡體   English   中英

我如何獲得一個采用通用類型的類,以從該類型的實例中調用方法?

[英]How can I get a class that takes generic type, to call a method from an instance of that type?

我有一個使用以下方法的“ Entity”基類(我沒有實現IEquatable,這很麻煩,所以我放棄了這種方法)

    virtual public bool Equals(Entity entity)
    {
        throw new Exception("The base Entity.Equals method should never be called");
    }

我有幾個擴展Entity的類。 每個人都會實現一個Equals方法,就像這樣。

    virtual public bool Equals(TestPlan other)
    {
        if (this.TestPlanType.Equals(other.TestPlanType) &&
            this.Name.Equals(other.Name) &&
            this.Description.Equals(other.Description) &&
            this.DatetimeCreated.Equals(other.DatetimeCreated) &&
            this.UserNameCreated.Equals(other.UserNameCreated) &&
            this.Duration.Equals(other.Duration) &&
            this.Scenarios.SequenceEqual(other.Scenarios)) return true;
        return false;
    }

我真的很想讓輸入的類型為TestPlan而不是Object。 (至少我認為我願意,我不想失去強類型)。

我意識到此方法不會“覆蓋”基類,因為我將其設置為虛擬公共而不是公共覆蓋。

我有一個采用通用類型的方法,該方法將調用.Equals()

    public int GetIdenticalEntityId<T>(T entity) where T : Entity
    {
        List<T> exitingEntities = LoadEntities<T>();
        foreach (T existingEntity in exitingEntities)
        {
            if (existingEntity.Equals(entity))
            {
                return existingEntity.Id;
            }
        }
        return -1;
    }

問題是exitingEntity.Equals()調用基類.Equals。

我如何獲得一個采用通用類型的類,以從該類型的實例中調用方法?

只需重寫基本的Equals(object other)方法。 很簡單。

您甚至可以通過在Entity類中聲明以下內容來使其成為必需的:

public override abstract bool Equals(object other);
public override abstract int GetHashCode();

現在,在您的類中, Equals方法將如下所示:

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

    if (other == null)
        return false;

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

    return this.TestPlanType.Equals(other.TestPlanType) &&
        this.Name.Equals(other.Name) &&
        this.Description.Equals(other.Description) &&
        this.DatetimeCreated.Equals(other.DatetimeCreated) &&
        this.UserNameCreated.Equals(other.UserNameCreated) &&
        this.Duration.Equals(other.Duration) &&
        this.Scenarios.SequenceEqual(other.Scenarios));
}

現在,如果您想實現IEquatable<T> ,它將非常簡單:

public bool Equals(TestPlan obj)
{
    return Equals((object)obj);
}

您也可以通過其他方式進行此操作:

public override bool Equals(object obj)
{
    return Equals(obj as TestPlan);
}

public bool Equals(TestPlan obj)
{
    if (obj == null)
        return false;

    // Same code as before
}

哦,您也應該實現GetHashCode以避免令人討厭的意外:

public override int GetHashCode()
{
    var hash = TestPlanType.GetHashCode();

    hash = (hash * 397) ^ Name.GetHashCode();
    hash = (hash * 397) ^ Description.GetHashCode();
    hash = (hash * 397) ^ DatetimeCreated.GetHashCode();
    hash = (hash * 397) ^ UserNameCreated.GetHashCode();
    hash = (hash * 397) ^ Duration.GetHashCode();
    hash = (hash * 397) ^ Scenarios.GetHashCode();

    return hash;
}

真的很重要。 例如,您團隊中的某人可能有一天想將您的對象用作字典中的鍵。 如果您從一開始就正確實現GetHashCode函數,則將在以后的代碼中避免此類陷阱。 這對於今天避免將來使用大型WTF來說是一個很小的代價。

到這里,這就是您真正需要的。

為了覆蓋一個函數,參數必須是同一時間。 因此,您的TestPlan.Equals應該類似於:

override public bool Equals(Entity entity)
{
    TestPlan other = entity as TestPlan;
    if (other == null)
       return false;
    if (this.TestPlanType.Equals(other.TestPlanType) &&
        this.Name.Equals(other.Name) &&
        this.Description.Equals(other.Description) &&
        this.DatetimeCreated.Equals(other.DatetimeCreated) &&
        this.UserNameCreated.Equals(other.UserNameCreated) &&
        this.Duration.Equals(other.Duration) &&
        this.Scenarios.SequenceEqual(other.Scenarios)) return true;
    return false;
}

暫無
暫無

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

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