我有一个映射到数据库中字段的类。该类仅关注字段的名称及其相关的.NET类型。 类型可以是字符串,整数,日期时间等
class Foo()
{
string Name { get; set; }
Type FooType { get; set; }
}
我有另一个继承自Foo的类,它为值添加了一个属性。现在我将值存储为对象,并使用switch语句根据基类FooType对值进行装箱。
class FooWithStuff() : Foo
{
object Value { get; set; }
}
有没有办法用泛型实现这个来为值赋予类型安全性?
修改:我已将关键要求设为粗体。在声明列表时说Foo需要一个类型。如果我对自定义类这样做,我会创建和接口并使用它。但是在这里我使用int,string,DateTime等.Int是一个结构,字符串是一个对象,所以一个Foo<对象>对两者都不起作用。
答案 0 :(得分:9)
class Foo
{
public string Name { get; set; }
public Type Type { get; set; }
}
class Bar<T> : Foo
{
public T Value { get; set; }
public Bar()
{
base.Type = typeof( T );
}
}
答案 1 :(得分:8)
像这样定义你的类:
class Foo<T> : IFoo
{
public Foo(string name)
{
Name = name;
}
string Name { get; set; }
T Value {get; set;}
Type FooType { get { return typeof(T); } }
}
然后,您可以将接口IFoo定义为:
string Name { get; set; }
Type FooType { get; set; }
并将列表声明为:
List<IFoo> list = new List<IFoo>();
答案 2 :(得分:2)
如果你想为Foo添加Value并让Foo成为通用的你可以做...
class Foo<T>
{
T Value {get; set;}
}
Foo<int> myFoo = new Foo<int>();
myFoo.Value = 7;
答案 3 :(得分:1)
我会使用接口而不是泛型类继承。
编辑:澄清。我会使用Interface for Foo,以及FooWithStuff的泛型类:
public interface IFoo
{
string Name{get;set;}
Type FooType{get;set;}
}
public class FooWithStuff<T>:IFoo
{
T Value {get;set;}
}
答案 4 :(得分:0)
是的,实际上你可以取消你的继承,只是..
public class Foo<T>
{
public string Name {get;set;}
public T Value {get;set;}
public Type FooType
{
get
{
return typeof(T);
}
}
}
另请注意,使用linq,您可以直接从列表中提取所需的类型,因此如果您只是因为某种原因对字符串字段感兴趣,那么可以...
List<object> list = getAllmyFoos();
foreach(Foo<string> sfoo in list.OfType<Foo<string>>())
{
...blah
}
编辑:添加了FooType。
答案 5 :(得分:-2)
我会使用2个接口重新编写:
public interface IFoo
{
string Name {get; }
Type Type { get; }
object Value {get; set;}
}
public interface IFoo<T> : IFoo
{
T Value {get; set}
}
然后实施它:
public class Foo<T> : IFoo<T>
{
private T value;
public Foo(string name, T value)
{
this.name = name;
this.value = value;
}
public string Name { get { return name; } }
public Type Type { get { return typeof(T); } }
public T Value
{
get { return value; }
set { value = value; }
}
object IFoo.Value
{
get { return value; }
set { value = (T)value; } // can check type before
}
}
这样,您也可以在非通用上下文中轻松使用IFoo接口。