c#:在派生类上具有不同返回类型的属性
本文关键字:返回类型 属性 派生 | 更新日期: 2023-09-27 18:14:39
我试图寻找这个问题的答案,但找不到太多,很可能是因为我不知道如何正确地寻找它,所以它开始了。非常感谢所有的帮助。
与看起来像
的基类abstract public class Property
{
private String name;
public Property(String propertyName)
{
name = propertyName;
}
public String Name
{
get { return name; }
}
abstract public override String ToString();
}
和类似
的派生类public class StringProperty : Property
{
private String value; // different properties for different types
public StringProperty(String propertyName, String value) : base(propertyName)
{
this.value = value;
}
public String Value // different signature for different properties
{
get { return value; }
}
public override String ToString()
{
return base.Name + ": " + value;
}
}
在运行时,函数接收一个"Property"对象的集合。我需要做些什么才能获得每一个的"价值"?我是否需要一个大的if
语句来查询每个"属性"对象的类型?如果没有,是否有更优雅的解决方案?
我试图定义一个抽象的"值"属性被覆盖,但由于返回类型不同,它没有工作。我也试着玩阴影的"值"属性,但我不能使它工作。使用类似com的变体的想法听起来也不太合适。
提前谢谢你。
编辑:我应该详细说明我要做的事情。不同的"文本框"代表不同的属性,并过滤正确的输入(取决于类型)。更新后的值被回读并存储。容器对象将被序列化为JSON,并在Android和iPhone客户端上反序列化,最终这些值将被传递到运行本地c++代码的层中,执行OpenGL操作。我事先不知道所有需要的属性,所以作为中间人,我想让我的代码尽可能健壮,同时能够提供OpenGL引擎。
你可以使用一个泛型类:
public class AnyProperty<T> : Property
{
private T value;
// ... etc
我强烈建议现在把基类变成一个接口:
public interface IProperty
{
public String Name { get; }
}
public class Property<T> : IProperty
{
public Property(String name, T value)
{
Name = name;
Value = value;
}
public String Name { get; private set; }
public T Value { get; private set; }
public override String ToString()
{
return string.Format("{0}: {1}", Name, Value)
}
}
下面是示例用法:
var intProp = new Property<int> ("age", 32);
var strProp = new Property<string> ("name", "Earl");
var enumProp = new Property<ColorEnum> ("eye color", ColorEnum.Magenta);
为了使构造更简单,您可以使用工厂方法:
public static Property<T> MakeProperty(string name, T value)
{
return new Property<T>(name,value);
}
var intProp = MakeProperty("age", 32);
var strProp = MakeProperty("name", "Earl");
var enumProp = MakeProperty("eye color", ColorEnum.Magenta);
<子>不一定推荐,而且有点OT:子>
你可以用一个扩展方法让它更时髦:
public static Property<T> AsProp<T>(this T value, string name)
{
return new Property<T>(name,value);
}
var intProp = 32.AsProp("age");
var strProp = "Earl".AsProp("name");
var enumProp = ColorEnum.Magenta.AsProp("eye color");
您只能使用object
类型。你想要完成什么?这里的问题不是你的类的结构,它是接收Property
对象集合的函数。甚至不可能将某些内容强制转换为未知类型,因为您不知道它需要存储在哪种类型的变量中。
所以基本上,你的Property.Value
属性需要类型为object
。在使用Property
对象的方法中,您需要使用它们做一些事情,并且您正在做的事情将决定它应该如何结构化。您正在打印值吗?从抽象PropertyValue
类继承*Value
类并重写ToString()
以返回适当的字符串表示
我对您的示例代码进行了一些更改,并得到了这个结果…
abstract public class Property
{
private readonly String _name;
public Property(String propertyName)
{
_name = propertyName;
}
public String Name
{
get { return _name; }
}
abstract public override String ToString();
}
public class StringProperty : Property
{
private readonly dynamic _value; // different properties for different types
public StringProperty(String propertyName, dynamic value)
: base(propertyName)
{
this._value = value;
}
public dynamic Value // different signature for different properties
{
get { return _value; }
}
public override String ToString()
{
return base.Name + ": " + _value;
}
}
static void Main(string[] args)
{
StringProperty sp = new StringProperty("A double", 3.444);
StringProperty sp2 = new StringProperty("My int", 4343);
StringProperty sp3 = new StringProperty("My directory", new DirectoryInfo("Some directory"));
StringProperty sp4 = new StringProperty("My null", null);
Console.WriteLine(sp);
Console.WriteLine(sp2);
Console.WriteLine(sp3);
Console.WriteLine(sp4);
}
}
值以预期的方式正确地打印到控制台。
这需要重新考虑一下,但是您是否考虑过使用动态类型(在.net中引入)
并不能真正解决你的问题,只是在回避它。属性可以是
Dictionary<String, dynamic>
,问题是它们直到运行时才被计算,所以编译器不支持键入
so given you wantint SomeValue = MyProperties[SomePropertyName] + 10;
如果MyProperties[SomePropertyName] = 10;//一切都好
如果是76.52或Fred,则在执行时抛出异常。
代码更简单、更干净,不需要额外的强制转换,所需的脚手架数量也很少,但是,您需要对广泛和虔诚地使用字典的代码进行单元测试。