簡體   English   中英

使用泛型類型時,如何從繼承的類而不是基類中調用方法?

[英]When using generic types, how can I call an method from an inherited class instead of a base class?

我有一個實現DependsOn()的基類

public class Entity
{
    protected Entity() { }

    public virtual List<Type> DependsOn()
    {
        return new List<Type>();
    }
}

我已經擴展了這個基類。

public class Waveform : Entity
{
    public virtual new List<Type> DependsOn()
    {
        return new List<Type> {typeof(Scenario)};
    }
}

我希望以下代碼返回“新列表{typeof(Scenario)}”,而不是返回一個空列表(它從基類而不是繼承的類調用DependsOn方法。我也通過調試器進行了驗證)

public virtual List<Entity> FindParents<T>(T possibleChild) where T : Entity
{
    List<Type> dependsOnTypes = possibleChild.DependsOn();
}

public void DeleteEntity<T>(T entity) where T : Entity
{
    List<Entity> parents = FindParents<T>(entity);
}

Waveform waveform = new Waveform();
DeleteEntity<Waveform>(waveform);

使用override而不是virtual new

virtual new創建一個新插槽,並定義一個新的函數,該函數本身是virtual但不與其基類共享vtable插槽。

每次在函數上使用new關鍵字時,都應認為它與基類中具有相同名稱的函數無關。 new允許您例如完全更改函數的簽名。

您尚未真正擴展基類,而是創建了一個具有相同名稱的新方法。 使用override關鍵字,如下所示:

public class Waveform : Entity
{
    public override List<Type> DependsOn()
    {
        return new List<Type> {typeof(Scenario)};
    }
}

在這種情況下,為什么需要覆蓋而不是新方法,是在運行時從包含子類的基類對象調用該方法的。 實際傳遞的元素是實體類型,在運行時會被波形填充,但是在運行時,實體對象不知道任何替代,因為子類實現隱藏了基類實現。

在原始格式下,調用所需的正確方法的唯一方法是使用Waveform對象(而不是實體),然后將調用正確的版本,如下所示:

 class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Waveform waveform = new Waveform();
            p.DeleteEntity<Waveform>(waveform);
        }

        public void DeleteEntity<T>(T entity) where T : Waveform
        {
            List<Entity> parents = FindParents<T>(entity);
        }

        public virtual List<Entity> FindParents<T>(T possibleChild) where T : Waveform
        {
            List<Entity> dependsOnTypes = possibleChild.DependsOn();
            return dependsOnTypes;
        }        
    }

    public class Entity
    {
        protected Entity() { }

        public virtual List<Entity> DependsOn()
        {
            return new List<Entity>();
        }
    }

    public class Waveform : Entity
    {
        public virtual new List<Entity> DependsOn()
        {
            return new List<Entity> { new Scenario() };           
        }
    }

    public class Scenario: Entity
    {
        int x;
        float y;
    }

暫無
暫無

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

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