3

私の質問はかなりばかげていると思います。別の言い方をすると、次のようになります。コードに夢中になりすぎて、今のところ回避策を見つけることができません。問題に長くとどまりすぎると、視野がどんどん狭くなります><。さらに、私は継承やポリモーフィズムなどを十分に理解していません。

ここにアイデアがあります:派生クラスの複数のリストがあり、それらのリストでジェネリック関数を呼び出したい(基本クラスのメンバーにアクセスして変更する)。継承には何か関係がある気がしますが、今のところ思い通りに機能させることができません。

これは私がやろうとしていることの非常に簡単な例です:

class Baseclass
{
    public int ID;
    public string Name;
}
class DerivedClass1 : Baseclass
{
}

private void FuncOnBase(List<Baseclass> _collection)
{
    // ...

    foreach (Baseclass obj in _collection)
    {
        ++obj.ID;
    }

    // ...
}
private void FuncTest()
{
    List<DerivedClass1> collection1 = new List<DerivedClass1>();
    collection1.Add(new DerivedClass1() { ID = 1 });
    collection1.Add(new DerivedClass1() { ID = 2 });
    collection1.Add(new DerivedClass1() { ID = 3 });

    FuncOnBase(collection1);   //  ==> forbidden, cannot convert the derived class list to the base class list
}
4

2 に答える 2

11

お奨めは分散が大好きです。AList<DerivedClass1>はaではありませんList<Baseclass>- そうでなければ、リストにFuncOnBasea を追加しようとしてBaseclassも、コンパイラはそれを見つけられません。

1 つのトリックは、ジェネリック メソッドを使用することです。

private void FuncOnBase<T>(List<T> _collection) where T : Baseclass
{
    // ...

    foreach (T obj in _collection)
    {
        obj.ID++;
    }

    // ...
}

上に示した例ではT、リストに a を追加できることに注意してください。特に、制約を追加するT : new()場合、または (たとえば) a を渡す場合に役立ちparams T[]ます。

IEnumerable<T>また、C# 4.0 / .NET 4.0 では共変になることに注意してください。そのため、 IEnumerable<Baseclass>(リストではなく) だけを渡した場合は、「そのまま」機能します。

private void FuncOnBase(IEnumerable<Baseclass> _collection)
{
   ///...
}
于 2009-10-28T07:37:56.500 に答える
2

のみを実行している場合は、次のようにforeach呼び出すFuncOnBase(IEnumerable<Baseclass> collection)ことができます。FuncTest

FuncOnBase(collection1.Cast<Baseclass>());

パラメーターを使用してメソッドを宣言し、List<T>その機能のみを使用するIEnumerable<T>と、コード内で意味のない API 制約が追加されます。

于 2009-10-28T07:38:08.967 に答える