接口是否需要属性,但不能指定所需的类型?

时间:2012-03-28 13:03:29

标签: c# .net generics types interface

我有一个简单的界面,定义如下:

interface iFace
{
   int Value { get; }
}

在这种情况下,任何实现iFace的类都必须具有名为Value类型为int的属性。这个接口的用法将是数据绑定,我不关心属性是什么类型。我有什么选择吗?我想避免这个解决方案:

interface iFace<T>
{
   T Value { get; }
}

因为我想在没有指定类型的情况下引用接口

编辑:

我希望能够将相同的界面应用于NumericUpDown控件和Trackbar控件。一个的value属性是十进制类型,另一个是int类型。

在这种情况下,将属性设置为object类型将不起作用。

3 个答案:

答案 0 :(得分:7)

如果您不关心它是否是严格类型的,请将属性类型更改为object。

答案 1 :(得分:3)

试试这个:

interface MyInterface
{
    Object MyProperty
    {
        get;
        set;
    }
}

class MyClass : MyInterface
{
    Object MyInterface.MyProperty
    {
        get
        {
            return this.MyProperty;
        }
        set
        {
            if (value is MyType)
                this.MyProperty = (MyType)value;
        }
    }

    public MyType MyProperty
    {
        get;
        set;
    }
}

答案 2 :(得分:1)

响应您的编辑:您遇到了.NET没有INumeric接口的众所周知的问题。它存在于我见过的源代码中,但它已被注释掉,这意味着微软已经认真对待它并遇到一些重大问题。

Danny Varod的解决方案很好;您还可以通过创建通用非泛型版本的接口来扩展它。另一种解决方案是向接口添加方法,这些方法表示您现在正在使用数学运算符的数值运算,例如Increment()

我会在这里调用界面IHasValue(部分原因是因为它有点喜剧):

interface IHasValue
{
    object Value { get; set; }
    void Increment();
    void Decrement();
}

interface IHasValue<TValue> : IHasValue { new TValue Value { get; set; } }

abstract class UpDownValueControl<T> : IHasValue<T>
{
    public T Value { get; set; }
    object IHasValue.Value
    {
         get { return this.Value; }
         set { this.Value = (T)value; }
    }
    public abstract void Increment();
    public abstract void Decrement();
}
class NumericUpDownControl : UpDownValueControl<decimal>
{
    public override void Increment() { Value++; }
    public override void Decrement() { Value--; }
    //rest of the implementation
}
class TrackbarControl : UpDownValueControl<int>
{
    public override void Increment() { Value++; }
    public override void Decrement() { Value--; }
    //rest of the implementation
}

令人沮丧的是,基类不能像递增和递减方法一样处理重复的代码,但至少这种方法允许基类处理除了重复之外的所有其他内容数学运算符代码。

我最终怀疑这种解决方案的复杂性增加了成本而不是收益;我想我更有可能选择Danny Varod的解决方案。