【问题标题】:Initialize array of key-value tuples of which the value has a generic type初始化其值具有泛型类型的键值元组数组
【发布时间】:2018-02-01 10:50:43
【问题描述】:

我需要一个键值元组数组,其中的值具有泛型类型。我不想将值声明为 System.Object。期望的用法是这样的:

Pair[] pairs = new Pair[]
{
  new Pair<int> { Name = "Age", Value = 44 },
  new Pair<string> { Name = "FirstName", Value = "Frank" },
};

Pair 定义如下:

public class Pair<T>
{
    public string Name { get; set; }
    public T Value { get; set; }
}

这在声明和初始化pairs 时会出现以下编译错误:

使用泛型 'Pair' 需要 1 个类型参数

如果我要这样更改代码:

Pair<int>[] pairs = new Pair<int>[]
{
   new Pair<int> { Name = "Age", Value = 44 },
   new Pair<string> { Name = "FirstName", Value = "Frank" },
};

它显然会满足Pair&lt;int&gt;,但不满足Pair&lt;string&gt;

无法将类型'Pair'隐式转换为'Pair'

如果我要这样更改代码:

Pair<object>[] pairs = new Pair<object>[]
{
    new Pair<int> { Name = "Age", Value = 44 },
    new Pair<string> { Name = "FirstName", Value = "Frank" },
};

那么编译错误是(两次):

无法将类型'Pair'隐式转换为'Pair'

---更新

我不想将 Pair.Value 声明为对象的原因是我想定义特殊的对,如下所示:

public class AgePair : Pair<int> { }

public class NamePair : Pair<string> { }

【问题讨论】:

  • @HimBromBeere:嗯,有接口:Pair&lt;IComparable&gt;Pair&lt;IConvertible&gt;。虽然很模糊。
  • 你能举例说明你想用这个 Pair 数组做什么吗?如果值的类型可以是任何东西,那么您似乎无法用它做任何有用的事情,因为您在编写使用此数组的代码时不知道该类型是什么,因此您编写的代码只能将其称为对象...
  • 如前所述,您不能使用开箱即用的泛型来做到这一点。然而,这取决于你想在这个兔子洞里走多远,我们在谈论多少种类型,你想保存多少击键,你可以编写一个奇怪而美妙的列表类和扩展方法世界
  • 查看我的更新。这些类是为 PDF 标签属性建模的公共 API 的一部分。
  • 没有办法在运行时确定类型数组并期望编译器知道这些类型。编译器不知道在运行时实际放入该数组的对象的任何事情

标签: c# generics


【解决方案1】:

虽然Pair&lt;int&gt;Pair&lt;string&gt; 共享Pair&lt;T&gt; 的类定义,但它们在运行时编译为完全不同的类型。因此,您不能将它们放入 IEnumerable&lt;T&gt;T[] 类型中。您根本无法(直接)这样做。

如果您让您的类Pair&lt;T&gt; 继承自类Pair,该类将Value 对象作为Type 对象返回,您可以使用IEnumerable&lt;Pair&gt;Pair[],并在使用该对象时分别检查typeof(Value) .

虽然这是非常不干净的,并且根据其类型而不是它的定义来更改结果的实现,这将违反 OOP 原则并增加隐藏的复杂性。这正是 Key-Value 存储通常以字符串字符串或字符串对象的形式完成的原因,其中对象是在复杂(多个属性和方法)类中定义的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2022-08-19
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 2019-08-21
    相关资源
    最近更新 更多