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在接口上调用方法时IColumnRule,我期望new 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 和编译器而言,您有两种无关的方法。

如何使用接口的对象 Parse(string) 从 IColumnRule 集合中调用子类泛型 T Parse(string) 方法......或者这是不可能的?

最简单的方法是有一个抽象类将其实现为:

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

    ...
}

(如果你有两个不同的方法名称,它会稍微简单一些。)

于 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 回答