0

これらのキーワードに関するたくさんの質問。私は最初の30かそこらをふるいにかけ、それからあきらめました。

私はそのようなインターフェースを持っています:

public interface IColumnRule
{
    int Length { get; set; }
    string Name { get; set; }
    object Parse(string toParse);
    int Position { get; set; }
    Type Type { get; }
}

public interface IColumnRule<T> : IColumnRule
{
    ColumnRule<T>.RuleFluentInterface<T> Configure { get; }
    new T Parse(string rowdata);
    Func<string, T> ParsingFunction { get; set; }
}

...アイデアは、IColumnRule<T>を利用して強く型付けされた列パーサーを作成するためにを実装することFunc<string, T>です。

IColumnRule<T>問題は、これらのコンクリートをIList<IColumnRule>コンテナに保管することです。には複数のタイプがありIColumnRule<T>、それぞれが異なるタイプに実装されています。インターフェイスでParseメソッドを呼び出すとき、サブクラスのメソッドが呼び出されることを期待していますが、ベースは実際に呼び出されているものです。IColumnRulenew Parse(string)Parse

インターフェイスの...T Parse(string)を使用するコレクションからサブクラスジェネリックメソッドを呼び出すにはどうすればよいですか?またはこれは不可能ですか?IColumnRuleobject Parse(string)

4

3 に答える 3

3

の実装でIColumnRule<T>は、準拠したParseメソッドを提供する必要があります。コードを考えると、これを行う最も簡単な方法は、サブクラスでオーバーライドされる基本クラスの保護された抽象メソッドを使用することです。

public abstract class ColumnRule : IColumnRule
{
    ...

    public object Parse(string rowdata)
    {
        return this.ParseInternal(rowdata);
    }

    protected abstract object ParseInternal(rowdata);
}

public class ColumnRule<T> : ColumnRule, IColumnRule<T>
{
    ...

    public new T Parse(string rowdata)
    {
        // strong-typed parse method
    }

    protected override object ParseInternal(string rowdata)
    {
        return this.Parse(rowdata); // invokes strong-typed method
    }
}
于 2013-03-01T17:43:03.017 に答える
1

IColumnRuleインターフェイスでParseメソッドを呼び出すと、サブクラスの新しいParse(string)メソッドが呼び出されることを期待していますが、実際に呼び出されるのはベースのParseです。

はい、そうです。型システムに関しては、CLRとコンパイラの2つの方法は関係ありません。

インターフェイスのオブジェクトParse(string)を使用してIColumnRuleのコレクションからサブクラスジェネリックTParse(string)メソッドを呼び出すにはどうすればよいですか...またはこれは不可能ですか?

最も簡単なアプローチは、これを次のように実装する抽象クラスを持つことです。

public abstract ColumnRuleBase<T> : IColumnRule<T>
{
    public object Parse(string toParse)
    {
        IColumnRule<T> genericThis = this;
        return genericThis.Parse(toParse);
    }

    ...
}

(2つのメソッド名が異なる場合は、少し簡単になります。)

于 2013-03-01T17:41:29.197 に答える
0

どういうわけかタイプを知っている必要があります:

List<IColumnRule> rules;  // populated from somewhere

foreach (IColumRule<int> rule in rules.OfType<IColumnRule<int>>()) {
    int foo = rule.Parse(rowData);
}

または、既知の要素をキャストするだけです。

int foo = ((IColumnRule<int>)rules[5]).Parse(rowData);
于 2013-03-01T17:41:29.987 に答える