具有相同接口但属性的类型不同的类

时间:2013-04-05 14:40:02

标签: c# .net types interface

我想有这样的设计:

public interface IDifferentTypes
{
}

public class IntegerType : IDifferentTypes
{
    public int value { get; set; }
}

public class StringType : IDifferentTypes
{
    public string value { get; set; }
}

public class DateTimeType : IDifferentTypes
{
    public DateTime value { get; set; }
}

但在界面中定义了属性“value”。

所以我可以这样说:

IDifferentTypes someInt = GetSomeInt(); // GetSomeInt() returns a IntegerType object
Assert.AreEqual(5, someInt.value);

IDifferentTypes someString = GetSomeString(); // GetSomeString() returns a StringType object
Assert.AreEqual("ok", someString.value);

问题是每种实现的值的类型是不同的,处理它的最佳方法是什么?

3 个答案:

答案 0 :(得分:9)

您可以定义通用接口(但它必须是属性,或者更严格来说,它不能是字段):

public interface IHasValue<T> {
  T Value { get; }
}

T是哪种类型,占位符,如果您愿意,您可以这样做:

public class HasStringValue : IHasValue<string> {
  public string Value { get; private set; }
}

答案 1 :(得分:5)

如果可以,请使用泛型:

var someInt = GetSomeInt();
Assert.AreEqual(5, someInt.Value);

var someString = GetSomeString();
Assert.AreEqual("ok", someString.Value);

// ...

public interface IDifferentTypes<T>
{
    T Value { get; set; }
}

public class IntegerType : IDifferentTypes<int>
{
    public int Value { get; set; }
}

public class StringType : IDifferentTypes<string>
{
    public string Value { get; set; }
}

public class DateTimeType : IDifferentTypes<DateTime>
{
    public DateTime Value { get; set; }
}

答案 2 :(得分:0)

interface IDifferentTypes
{
    Object Value { get; set; }
}

class StringType : IDifferentTypes
{
    string _value;

    public Object Value
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value as string;
        }
    }
}

但这意味着每次使用StringType.Value时,您都需要重新制作它。您可能还希望公开特定类型的公共访问者。您还可能希望添加一些保护以防止分配错误的类型:

class StringType : IDifferentTypes
{
    public String StringProperty { get; set; }

    public Object Value
    {
        get
        {
            // works with any type that can auto cast to `Object`
            return StringProperty;
        }
        set
        {
            // Optional
            if( typeof(string) != value.GetType() )
            {
                throw new MyException();
            }

            // works for any nullable type
            StringProperty = value as string;

            // OR

            // throws an exception if conversion fails
            StringProperty = (string)value;
        }
    }
}