簡體   English   中英

C#抽象類返回派生類型枚舉器

[英]C# abstract class return derived type enumerator

如果我有一個抽象類,有什么辦法可以返回派生類類型的枚舉器? 或者我是否必須在基類或泛型方法中使用泛型? 這是我正在嘗試做的一個非常愚蠢的例子 -

public abstract class Person {
    public IEnumerable<MyType> Search() {
        DbDataReader reader = Database.Instance.ExecuteReader(sql);
        while(reader.Read()) {
            MyType row = new MyType();
            row.Load(reader);
            yeild return row;
        }
    }

    private Load(DbDataReader reader) {
        //load instance from reader row
    }

    //declare properties that can be searched, such as Location
}

public class Programmer : Person {
    //declare properties that can be searched, such as Language
}

然后我想在其他地方打電話

Programmer programmer = new Programmer();
programmer.Location = "My city";
programmer.Language = "C#";
foreach(Programmer programmer in programmer.Search())
{
    //display list of c# programmers in my city
}

我知道我可以用一般的方法來做這個,比如Search<T>() ,但我希望能夠從一個不完全知道Person類型的類中調用搜索函數(例如,一個基類) AJAX處理程序的類)

如果無法做到這一點,任何人都可以給我一個例子或理由為什么不呢? 或者只是太難實現編譯器?

沒有理由你不能使你的搜索方法通用:

public IEnumerable<T> Search<T>() where T : MyType, new() {
    DbDataReader reader = Database.Instance.ExecuteReader(sql);
    while(reader.Read()) {
        T row = new T();
        row.Load(reader);
        yield return row;
    }
}

並調用programmer.Search<Programmer>()

MyType來自哪里? 那應該是Person嗎?

http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx

虛方法返回類型的協方差是一個相當頻繁請求的功能,如果我有它,我會使用它。 它從未成為標准,因為(1)CLR不支持它; 我們必須在幕后生成大量的幫助代碼才能使其工作,或者說服CLR團隊改變(C ++ / CLI團隊做了前者)(2)在大多數情況下你可以自己生成必要的輔助函數很容易 只需創建一個具有正確返回類型的“新”方法,將其實現委托給虛方法,(3)Anders不認為它是一個特別重要的特性。 - 埃里克

所以,不,這是不可能的,是的,這是因為它太難了。

如果您使用這種“漂亮”用法搜索方法,我建議使用ExtensionMethod。 使用Ext,您不必兩次定義實體的有效類型。 programmer.Search<Programmer>() => programmer.Search()

public static PersonExtensions
{
    public static IEnumerable<TType> Search<TType>(this TType row) : where TType : new(), Person 
    {
        DbDataReader reader = Database.Instance.ExecuteReader(sql);
        while(reader.Read()) {
            var row = new TType()
            row.Load(reader);
            yeild return row;
        }
    }
}

@ben dotnet:沒有必要明確地傳遞有效類型的事實並不是因為它是一個擴展方法。 這是由於類型推斷機制,並且也會出現在任何一種方法(擴展或常規)上。

在這樣的方法原型

public static IEnumerable<TType> Search<TType>(this TType row) : where TType : new(), Person

編譯器已知TType與行中出現的4次相同。 因此,在調用方法時,知道programmer的類型就知道它將是<...>之間的相同類型就足夠了。 這就是為什么我們可以省略它。 如果沒有帶this關鍵字前綴的參數,它也可以工作。

您可以在基類中使用泛型類型,並在派生類中將泛型類型定義為派生類。

public abstract class Person<T> where T : Person<T>
    {
        public IEnumerable<T> Search()
        {
            DbDataReader reader = Database.Instance.ExecuteReader(sql);
            while (reader.Read())
            {
                var row = new T();
                row.Load(reader);
                yield return row;
            }
        }

        protected virtual void Load(DbDataReader reader){}
    }

    public class Programmer : Person<Programmer>{}

暫無
暫無

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

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