在实现具有对象类型属性的接口的类中更改属性类型

我正在编写一个TemplateEngine,它允许我在基于文本的文件中使用自己的标记。 我想在应用程序成熟时添加控件作为插件。 目前我有一个如下结构:

interface IControl string Id object Value class Label : IControl string Id string Value class Repeater : IControl string Id List Value 

现在,您将使用Value属性立即在Repeater类中看到奇怪的部分。 我希望在界面中使用Value类型作为对象将允许我灵活地扩展控件,因为我继续。 编译器不喜欢这个,我猜是有充分理由的。

结论:我正在尝试让所有控件类实现相同的接口,但Value属性具有不同的类型。

有没有人有任何建议如何实现这一目标?

注意:请不要建议使用Spark View Engine进行模板化。 我有理由为自己创造额外的工作。

通常, Repeater会实现不同的东西,例如IItemsControl

编辑1

(为简洁起见,删除)

编辑2

好吧,你当然可以使用显式接口实现:

 interface IControl { string Id { get; set; } object Value { get; set; } } class Label : IControl { public string Id { get; set; } public string Value { get; set; } object IControl.Value { get { return this.Value; } set { this.Value = (string)value; } } } class Repeater : IControl { public string Id { get; set; } public IList Value { get; set; } object IControl.Value { get { return this.Value; } set { this.Value = (IList)value; } } } 

你也可以使用generics:

 interface IControl { string ID{get;set;} T Value{get;set;} } class SomeControl : IControl { public string ID{get;set} public string Value{get;set;} } class SomeOtherControl : IControl { public string ID{get;set} public int Value{get;set;} } 

如果它只是一个需要改变的返回值,我比明确的界面想法更喜欢这个。 但是,我认为如果你有几个属性,每个属性将返回一个不同的类型,你不希望有IControl。 至少,我不会。 在这种情况下,我会建议显式接口。

当然,如果您无法访问IControl的源代码,这将无效。

编辑:有一个错字。 固定

不,编译器不允许相同的名称字段具有不同于派生类中的接口中定义的数据类型。

属性(因为接口中不允许任何字段)应该在派生类中实现,并且它们需要具有相同的数据类型。 所以,如果没有明确的声明,你不可能使用属性。

但是,如果你使一个函数返回Value,那么它可以工作,但你需要检查返回类型,因为返回类型应该与函数匹配,否则你将得到错误,即接口的函数没有实现。

  interface IControl { object Value(); } class A : IControl { string m_value = string.Empty; public object Value() { return m_value; } }; class B : IControl { List m_value = new List(); public object Value() { return m_value; } }; .... object o = new B().Value(); if (o is List) MessageBox.Show("List"); 

[更新]
如果明确定义属性的主体,则必须小心。 如果没有仔细执行,那么为两个属性设置一个名称将是危险的。

这两个属性如果包含不同的定义,那么对于接口和类的最终使用来说是无法解释的。

  public IList Value object IControl.Value 

看这个例子:

  ... class Repeater : IControl { List m_Value = new List(); public IList Value { get { return this.m_Value; } set { this.m_Value = (IList)value; } } object IControl.Value { get { return this.m_Value; } set { this.m_Value = new List(); this.m_Value.Add(new Label()); this.m_Value.AddRange((List)value); } } } ... Repeater b = new Repeater(); IControl i = b; List list = new List(); list.Add(new Repeater()); i.Value = list; 

您可以观察到,当通过IControl添加数据时,Repeater中的列表容器将具有不同的值(因为IContainer.Value的显式定义)。