2013-03-01 56 views
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>,每种类型都执行不同的类型。当我调用IColumnRule接口上的Parse方法时,我期待调用子类的new Parse(string)方法,但实际上调用的是基础Parse

如何使用接口的object Parse(string)来调用IColumnRule集合中的子类通用T Parse(string)方法...或者这是不可能的?

+0

这是明确说明你在声明'new'函数时得到的行为。请参阅[这里](http://msdn.microsoft.com/en-us/library/ms173153%28v=vs.110%29.aspx)。 – Bobson 2013-03-01 17:40:28

+0

你几分钟前在你的问题中已经有了你的实现细节,但删除了它们。这有助于解释你为什么遇到问题。我用更详细的解决方案更新了我的答案,该解决方案可以帮助您。 – 2013-03-01 18:53:00

+0

@ p.s.w.g是的,我认为这是太多的信息,将是一个TL; DR有点儿。你的答案是我正在寻找的;谢谢。 – 2013-03-01 18:59:12

回答

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 
    } 
} 
+0

虽然我不能把它放到一个集合中,对吗? – 2013-03-01 18:30:11

+0

@JeremyHolovacs你可以创建一个'IColumnRule'的集合,很容易做'rulesCollection.Select(r => r.Parse(rowdata))' – 2013-03-01 18:34:25

+0

这基本上就是我最终做的。谢谢! – 2013-03-01 18:58:14

0

当我调用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); 
    } 

    ... 
} 

(如果你有两个方法名是不同的,这将是稍微简单一些。)

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);