【问题标题】:A List of varying types?不同类型的列表?
【发布时间】:2010-11-26 05:49:12
【问题描述】:

我想创建一个数据列表,从一个方法传递到另一个方法,但是我不能使用结构,因为这个列表中包含的数据会因输入而异。

例如

if (x == 1) {
   a = 1 
   b = true   
   c = 42
   d = "hello"
}

if (x == 2) {
   a = 2
   b = 'g'
   c = "sup"
}

我相信我的选择是这样的:

  1. 创建一个数组或字符串列表,并将数据转换回原来的字符串。这很混乱,可能会导致无法解释的输入错误,但不会那么糟糕,因为它会在运行时被检测到。
  2. 为每种可能性创建一个结构 - 这是一种好的做法吗?
  3. 不知何故使用泛型。据我所知,虽然泛型是类型安全的但不是类型严格的,但它们必须在使用之前转换为类型。例如,如果我想要一个项目列表,我需要将它们转换为字符串,就像解决方案 1 中发生的那样,这使得这无用。

那么我的问题是,这些选项中哪一个是最好的?或者是否有使用某种我不知道的通用类型的替代选项?每种情况下可能变量的数量可能会改变,就像它们的类型一样。我希望能够将单个 List 或 Array 返回给调用方法,以便它可以适当地处理结果。它将知道如何根据 a 的值处理每组数据,因为它将是“动作选择”标识符。我也知道每次将它们转换为对象并返回非常密集,所以我宁愿避免这种情况。

这可能很简单,但它让我很难过......

【问题讨论】:

  • 为了提供更多信息,基本上这是试图根据用户的选择从输入字符串中解释各种数据。如果他们说一件事,我需要检查该数据然后抓取它,列出这些数据及其类型(各种事物都来自这些信息)。问题是我想让它可扩展,所以我总是可以添加东西而不必遵守严格的结构,而且我不应该在使用时重铸所有东西。我喜欢 ArrayList 建议以及重构建议。我会尝试修改它。

标签: c# .net arrays list types


【解决方案1】:

基本上,您需要一个类型为 Object 的列表,然后是的,您处于回滚模式。

我的问题是,从结构上讲,您如何知道哪些索引属于哪种类型?这听起来充其量只是一个痛苦的解决方案。

如果你真的需要在列表中存储不同的类型,也许可以尝试一个包含每种类型成员的结构,以及一个指示表示哪种数据类型的标志。然后对该结构使用通用集合。类似的东西(在我的脑海中)

struct FooType
{
    public string StringValue;
    public bool BoolValue;
    public int IntValue;
    public char CharValue;

    public string DataType;

    // You'd probably want constructors too
}

然后是通用列表:

var values = new List<FooType>();

现在您可以使用该类型在列表中添加和删除条目,这将指示核心数据的真正含义。

我还是不喜欢这个答案;听起来您的设计可能会尝试做太多事情并且可能存在重构机会,但是由于我没有看到更多您的代码或意图,所以我所能做的就是回答您的要求。 :)

【讨论】:

    【解决方案2】:

    您可以使用Dictionary/Hashtable 表示数据项,然后将这些字典添加到List

    如果需要,您还可以在字典值中添加额外的类型信息。

    【讨论】:

      【解决方案3】:

      抱歉,这不是与代码相关的答案:可能隐藏在这种构造背后的错误设计。确保你知道自己在做什么,否则事情可能会反击。

      如果确实需要事先不知道您使用的字段的类型,这需要一种方法来保存数据及其类型,例如

      struct foo {
          private object _value;
          private string _type;
          foo(string myType, object myValue) {
              _value = myValue;
              _type = myType;
          } 
      }
      

      然后使用泛型来处理业务逻辑。

      【讨论】:

        【解决方案4】:

        .NET 中的一般原则是每个类型都可以转换为 System.Object(尽管它可能涉及装箱)。您可以使用类似的方法

        void Foo(params object[] parameters) { ... }
        

        或者使用 System.Collections.ArrayList 类。

        “问题”是当你想使用这样的值时,你需要如下代码:

           if (parameters[i] is string)
           {
              string s = (string) parameters[i];
              ...
           }
        

        【讨论】:

          【解决方案5】:

          由于您事先不知道该列表将包含什么内容,因此使用ArrayList 似乎是一个很好的例子。

          如果您想使用键返回值,请考虑使用Hashtable

          【讨论】:

            猜你喜欢
            • 2016-01-19
            • 1970-01-01
            • 2017-03-21
            • 1970-01-01
            • 2015-06-05
            • 1970-01-01
            相关资源
            最近更新 更多