C# C语言中的设计问题:泛型还是多态性?
我需要一些设计方面的帮助。我努力做到的是: 我有一个叫做Document的主类。此类具有属性类的列表。这些属性类有一些共同的属性,比如Identity和Name,但它们在一个我称之为Value的属性上有所不同。每个不同的属性类的值类型都不同,类型为string、integer、List、DateTime、float、List以及由多个属性组成的类。一个例子是我称之为PairAttribute的类,它有两个属性:Title和Description 我试图实现的是属性子类的Value属性的类型安全性,并且这些子类应该能够添加到文档类的属性列表中。我本可以只创建一个属性类,该属性类具有object类型的Value属性,并且可以使用它来完成,但这正是我在这里试图避免的 公共属性Identity和Name应该放在基类中,我想,让我们称之为AttributeBase类。但是我想有一个子类,比如StringAttribute,其中Value属性是string类型,IntegerAttribute类中Value属性是Integer类型,StringListAttribute中Value属性是List类型,PairAttribute类中Value是具有多个属性的类,等等C# C语言中的设计问题:泛型还是多态性?,c#,generics,polymorphism,C#,Generics,Polymorphism,我需要一些设计方面的帮助。我努力做到的是: 我有一个叫做Document的主类。此类具有属性类的列表。这些属性类有一些共同的属性,比如Identity和Name,但它们在一个我称之为Value的属性上有所不同。每个不同的属性类的值类型都不同,类型为string、integer、List、DateTime、float、List以及由多个属性组成的类。一个例子是我称之为PairAttribute的类,它有两个属性:Title和Description 我试图实现的是属性子类的Value属性的类型安全性
你知道我该如何实现这一点吗?这是一个解决方案,我应该去在所有或它是一个更好的方式来解决这种类型的安全问题?我希望通过代码示例进行澄清:您不需要指定语言,但是Java和C使用的术语泛型描述的功能在其他语言中,如ML和Haskell中经常被调用。相反,Java和C中的共同含义实际上更精确地称为 关键是,无论您使用的是子类型多态性还是参数多态性,您的问题都需要多态性,因此我认为您走在了正确的轨道上 问题实际上归结为:参数多态性何时比子类型多态性更好?答案其实很简单:当它需要你写更少的代码时
所以,我建议您对这两种方法进行原型化,然后看看哪一种方法会导致更简单、更容易理解的代码。然后这样做。您不需要指定语言,但是Java和C使用的术语泛型描述的特性在其他语言(如ML和Haskell)中经常被调用。相反,Java和C中的共同含义实际上更精确地称为 关键是,无论您使用的是子类型多态性还是参数多态性,您的问题都需要多态性,因此我认为您走在了正确的轨道上 问题实际上归结为:参数多态性何时比子类型多态性更好?答案其实很简单:当它需要你写更少的代码时
所以,我建议您对这两种方法进行原型化,然后看看哪一种方法会导致更简单、更容易理解的代码。然后这样做。您可以使用泛型属性而不是继承/方法多态性进行传递,但您需要将它们存储在某个列表中,为此您需要一个接口,因为.Net中的数据存储不能是未定义泛型类型的集合,如果您要定义它们,则无法在其中混合类型:
public interface IAttribute {
string Identity { get; set; }
string Name { get; set; }
T GetValue<T>();
}
public class Attribute<T> : IAttribute
{
public string Identity { get; set; }
public string Name { get; set; }
public T Value { get; set; }
public Tret GetValue<Tret>() {
return (Tret)(Object)Value;
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
List<IAttribute> lst = new List<IAttribute>();
Attribute<string> attr1 = new Attribute<string>();
attr1.Value = "test";
Attribute<int> attr2 = new Attribute<int>();
attr2.Value = 2;
lst.Add(attr1);
lst.Add(attr2);
string attr1val = lst[0].GetValue<string>();
int attr2val = lst[1].GetValue<int>();
}
}
TretObject实际上不改变类型,它只对T进行装箱,Tret不使用中间变量就取消装箱。如果在调用GetValue时错过了正确的类型,这当然会失败。即使发送了兼容的类型,比如Value is integer,并且您执行GetValue->,因为不允许将整数取消装箱到double中
装箱/取消装箱的速度不如强制转换快,但它确保了类型安全性得到保护,据我所知,在编译时已知的接口中,无法以其他方式使用泛型
所以这应该是类型安全的。。。没有太多的代码。您可以使用泛型属性而不是继承/方法多态性进行传递,但您需要将它们存储在某个列表中,为此您需要一个接口,因为.Net中的数据存储不能是未定义泛型类型的集合,如果要定义它们,则无法在其中混合类型:
public interface IAttribute {
string Identity { get; set; }
string Name { get; set; }
T GetValue<T>();
}
public class Attribute<T> : IAttribute
{
public string Identity { get; set; }
public string Name { get; set; }
public T Value { get; set; }
public Tret GetValue<Tret>() {
return (Tret)(Object)Value;
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
List<IAttribute> lst = new List<IAttribute>();
Attribute<string> attr1 = new Attribute<string>();
attr1.Value = "test";
Attribute<int> attr2 = new Attribute<int>();
attr2.Value = 2;
lst.Add(attr1);
lst.Add(attr2);
string attr1val = lst[0].GetValue<string>();
int attr2val = lst[1].GetValue<int>();
}
}
TretObject实际上不改变类型,它只对T进行装箱,Tret不使用中间变量就取消装箱。如果在调用GetValue时错过了正确的类型,这当然会失败。即使发送了兼容的类型,比如Value is integer,并且您执行GetValue->,因为不允许将整数取消装箱到double中
装箱/取消装箱的速度不如强制转换快,但它确保了类型安全性得到保护,据我所知,在编译时已知的接口中,无法以其他方式使用泛型
所以这应该是类型安全的。。。而且没有很多代码