【问题标题】:Is it possible to add KeyValuePair<> as Type of params in C#是否可以在 C# 中添加 KeyValuePair<> 作为参数类型
【发布时间】:2017-12-02 02:04:41
【问题描述】:

如标题所述;我有(如下所示)一个结构类型的数组。 但是尝试从中提取数据是行不通的,因为它被评估为 Object 类型。 如果不可能的话,如果可能的话,我真的很喜欢这种态射。

    private Entity makeEntity(params KeyValuePair<String, object>[] fields)
    {
        Entity entity = new Entity();

        IEnumerator cons = fields.GetEnumerator();
        Field field;
        Value value;
        while (cons.MoveNext()){
            value = new Value();
                value.value = cons.Current.Value;
            field = new Field();
                field.name = cons.Current.Key;
                field.values.Add(value);
                entity.fields.Add(field);
        }

        return entity;
    }

【问题讨论】:

  • 我相信如果有问题,它与.NET('object'类型)有关。
  • 在将cons.Current.Value 分配给value.value 之前,您是否尝试过将其转换为您需要的任何类型?否则我不确定我是否破坏了你的要求:)
  • 说明你想做什么。标题没有帮助。 params 具有此处未使用的特定语法。您明确表示您希望接收 object 值。你一开始想做什么?您是否尝试在不使用 dynamic 的情况下传递 dynamic 类型?
  • 另外,我猜你可以简单地使用foreach KeyValuePair&lt;string, object&gt; keyValuePair in fields) 而不必如此明确地使用枚举器。
  • 更简单:return new Entity {Values=fields.Select(pair=&gt;pair.Value).ToArray(); Fields=fields.Select(pair=&gt;pair.Key).ToArray();};。不是说我明白这一点,除非 Entity 实现 DynamicObject ?那为什么不使用字典呢?

标签: c# structure enumerable


【解决方案1】:

为什么不使用对象(或匿名对象)呢?

private Entity makeEntity(object obj)
{
    Entity entity = new Entity();
    foreach(var kvp in new RouteValueDictionary(obj))
    {
      entity.fields.Add(new Field {name=kvp.Key, values={new Value {value=kvp.Value}});
    }

    return entity;
}

在大多数情况下使用起来要容易得多:

var x = makeEntity(new {Field1=Value1, Field2=Value2, Field3=Value3});

【讨论】:

  • 如果您愿意,您甚至可以将其转换为 LINQ Select 的单个返回,这会更短,但我会留给您。假设 Entity.fields 是可设置的。
【解决方案2】:

最简单的解决方法是更改​​cons的声明类型:

IEnumerator<KeyValuePair<string, object>> cons = ((IEnumerable<KeyValuePair<string, object>>)fields).GetEnumerator();

但是,您应该只使用 foreach 来迭代元素:

foreach(var kvp in fields)
{
    ...
}

【讨论】:

    【解决方案3】:

    我认为在

    中提出的强制转换功能

    What is the best way to convert an IEnumerator to a generic IEnumerator?

    可能是您正在寻找的解决方案:

    IEnumerator<T> Cast<T>(IEnumerator iterator)
    {
        while (iterator.MoveNext())
        {
            yield return (T) iterator.Current;
        }
    }
    

    你在你的代码中这样调用它:

    ...
    var cons = Cast<KeyValuePair<String, object>>(fields.GetEnumerator());
    ...
    

    【讨论】:

    • @Lee - 你可以这样声明,但你仍然必须进行强制转换,因为fields.GetEnumerator() 为你提供了非通用版本。
    • @HelmutD - 令人惊讶的是,fields.GetEnumerator 只返回非泛型 IEnumerator 接口,但您可以通过将源数组转换为 IEnumerable&lt;T&gt; 而不是包装枚举器来访问它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2013-01-16
    • 2011-08-18
    • 2014-04-15
    相关资源
    最近更新 更多