【发布时间】:2009-03-10 19:52:17
【问题描述】:
假设我有一个数据对象,但这个对象可以保存多种类型的数据之一。
class Foo
{
int intFoo;
double doubleFoo;
string stringFoo;
}
现在,我想创建一个访问器。获取此数据的某种方式。显然,我可以创建多个访问器:
public int GetIntFoo();
public double GetDoubleFoo();
public string GetStringFoo();
或者我可以创建多个属性
public int IntFoo { get; set; }
public double DoubleFoo { get; set; }
public string StringFoo { get; set; }
我不认为这是一个非常好的设计。它要求客户端代码比它应该更关心类型。更重要的是,我真的只需要这个类的一个值,上面将允许同时分配每种类型中的一个。不好。
一种选择是使用泛型。
class Foo<T>
{
public T TheFoo { get; set; }
}
但是,这不会创建一个 Foo,它会创建一个 Foo
我可以从 FooBase 派生 Foo
一个不同的泛型选项是使用这样的东西:
class Foo
{
string stringRepresentationOfFoo;
public T GetFoo<T>() { return /* code to convert string to type */ }
}
当然,问题是任何类型的 T 都可以通过,坦率地说,它有点忙。
我也可以将值装箱并返回一个对象,但是没有类型安全性。
理想情况下,我希望对所有 Foo 都一视同仁,但我希望类型安全,这样如果没有 StringFoo,我什至无法编译对 StringFoo 的引用。
Foo foo = new Foo("Foo");
string sFoo = foo.Value; // succeeds.
Foo foo = new Foo(0);
int iFoo = foo.Value; // succeeds
string sFoo = foo.Value; // compile error
也许这甚至是不可能的......我必须做出一些妥协,但也许我错过了一些东西。
有什么想法吗?
编辑:
好的,正如 daniel 指出的那样,运行时类型的编译时检查是不切实际的。
在这里做我想做的事情的最佳选择是什么?即,对所有 Foo 都一视同仁,但仍然有一个相对健全的访问机制?
EDIT2:
我不想将值转换为不同的类型。我想为该值返回正确的类型。也就是说,如果它是一个双精度,我不想返回一个 int。
【问题讨论】:
-
如果你的 Foo 实例可以是任何值,你的消费者如何知道它应该将结果存储在什么类型的变量中?
-
我认为您试图在 C#(一种强类型语言)中获得类似于松散类型语言的行为,这是否正确?
-
不,你不正确。我正在尝试使用强类型。这就是重点,否则我只会使用对象和演员。
-
至于消费者如何知道什么类型,它不必知道。在对象使用的上下文中,只有一种有效类型,这也是他们将分配 Foo 值的类型。如果他们尝试使用无效类型,最好抛出编译时错误,但这是不可能的
-
所以我可能不得不使用某种运行时异常,这不好,但我没有看到很多选择。问题是,这无论如何都不应该发生,而且会是一个明显的错误。
标签: c# generics type-safety