我试图寻找这个问题的答案,但找不到太多,很可能是因为我不知道如何正确地寻找它,所以就这样吧。非常感谢所有帮助。
使用类似
的基类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
语句来查询每个“Property”对象的类型?如果没有,是否有更优雅的解决方案?
我试图定义一个要覆盖的抽象“Value”属性,但由于返回类型不同,所以它不起作用。我也试过玩“价值”属性,但我不能让它工作。使用类似COM的变体的想法也听起来不太合适。
提前多多感谢。
编辑:
我应该添加一些关于我要做什么的细节。属性显示在Winforms应用程序中。不同的“TextBox”表示不同的属性,并且过滤以获得适当的输入(取决于类型)。读回并存储更新的值。容器对象将被序列化为JSON并在Android和iPhone客户端上反序列化,最终这些值将传递到运行OpenGL内容的本机C ++代码的层中。我事先并不知道所有需要的属性,所以作为中间人,我想让我的代码尽可能健壮,同时能够提供OpenGL引擎。
答案 0 :(得分:13)
您可以使用通用类:
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");
答案 1 :(得分:3)
您只需使用object
类型即可。你想达到什么目的?这里的问题不是类的结构,而是接收Property
个对象集合的函数。甚至不可能将某些内容转换为未知类型,因为您不知道需要存储哪种类型的变量。
基本上,您的Property.Value
属性必须是object
类型。在使用Property
对象的方法中,您需要对它们执行某些操作,而您正在执行的操作将决定它应该如何构建。你打印价值了吗?让*Value
类继承自抽象PropertyValue
类并覆盖ToString()
以返回适当的字符串表示。
答案 2 :(得分:2)
我对您的示例代码进行了一些更改并获得了此结果...
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);
}
}
以预期的方式将值正确打印到控制台。
答案 3 :(得分:2)
这需要重新考虑一下,但您是否考虑使用动态类型(在.net4中引入)
并没有真正解决你的问题,而是侧重于它。 您的属性可以基本上只是一个
Dictionary<String, dynamic>
,问题是它们直到运行时才被评估,所以你没有编译器支持输入。
所以你想要的 int SomeValue = MyProperties [SomePropertyName] + 10;
所以如果 MyProperties [SomePropertyName] = 10; //一切都很好
如果是76.52或Fred,则添加将在执行时抛出异常。
代码更简单,更清晰,没有额外的铸造,所需的脚手架数量很少,但是,你需要对广泛和宗教地使用字典的代码进行单元测试。