具有相同接口但属性类型不同的类
本文关键字:类型 属性 接口 | 更新日期: 2023-09-27 18:07:30
我想要这种设计:
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);
问题是,每个实现的值类型不同,处理这种情况的最佳方法是什么?
您可以定义一个通用接口(但它必须是一个属性,或者更严格地说,它不能是一个字段(:
public interface IHasValue<T> {
T Value { get; }
}
其中T
是类型,如果你愿意的话,它是一个占位符,你可以这样做:
public class HasStringValue : IHasValue<string> {
public string Value { get; private set; }
}
如果可以,请使用泛型:
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; }
}
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;
}
}
}