简体   繁体   English

静态非泛型类中的泛型函数?

[英]Generic Function within a static non-generic class?

I have a static class "Extras" in my project that I use to put methods that don't belong in any other class, such as converters. 我的项目中有一个静态类“ Extras”,用于放置不属于任何其他类的方法(例如转换器)。 I want to add a function called DictionaryFromArrays() that I use to create a Dictionary based on an two arrays passed as parameters: one filled with keys, and another filled with values. 我想添加一个称为DictionaryFromArrays()的函数,该函数用于基于作为参数传递的两个数组创建一个Dictionary:一个数组填充键,另一个数组填充值。 However, I'm new to generics, and using 但是,我是泛型新手,并且使用

public static Dictionary<T, U> DictionaryFromArrays(T[] keys, U[] values)

clearly doesn't work. 显然是行不通的。

I know that this is obviously not the correct way to use generics, but how would one create a function that has that effect? 我知道这显然不是使用泛型的正确方法,但是如何创建具有这种作用的函数呢?

您应该为方法声明通用类型( DictionaryFromArrays<T, U> ):

public static Dictionary<T, U> DictionaryFromArrays<T, U>(T[] keys, U[] values)

You can do it like this: 您可以这样做:

public static Dictionary<T, U> DictionaryFromArrays<T,U>(T[] keys, U[] values)
{
     var dictionary = new Dictionary<T, U>();
     if (keys.Length == values.Length)
     {
         for (int i = 0; i < keys.Length; i++)
         {
             dictionary.Add(keys[i], values[i]);
         }
     }
     else
     {
         /* throw exception */
     }

     return dictionary;
}

You are almost there: 您几乎在那里:

 public static Dictionary<T, U> DictionaryFromArrays<T,U>(T[] keys, U[] values) 
 {return ....;}

You need to specify types in the signature, not just in arguments/return value. 您需要在签名中指定类型,而不仅仅是参数/返回值。

Note: this pattern is heavily used in LINQ's Enumerable - static extension methods in static non-generic class. 注意:此模式在LINQ的Enumerable静态非泛型类中的静态扩展方法中大量使用。

The generic type was missing: <TKey, TValue> before the round brackets of the method. 缺少通用类型:方法的圆括号之前为<TKey, TValue>

Here is a possible implementation which should work: 这是可能可行的实现:

public static Dictionary<K, V> DictionaryFromArrays<K, V>(K[] keys, V[] values, bool skipDuplicates)
{
    if (keys == null) throw new ArgumentNullException("keys");
    if (values == null) throw new ArgumentNullException("values");
    if(keys.Length != values.Length) throw new ArgumentException("Keys and Values must have the same length!");

    if (!skipDuplicates)
        return keys.Zip(values, (k, v) => new KeyValuePair<K, V>(k, v))
            .ToDictionary(kv => kv.Key, kv => kv.Value);
    else
    {
        Dictionary<K, V> dict = new Dictionary<K,V>();
        for (int i = 0; i < keys.Length; i++)
        {
            K key = keys[i];
            if (!dict.ContainsKey(key))
                dict.Add(key, values[i]);
        }
        return dict;
    }
}

You can use LINQ Select with index version. 您可以将LINQ Select与索引版本一起使用。

public static Dictionary<T, U> DictionaryFromArrays<T,U>(T[] keys, U[] values)
{
    return keys
      .Select((k, idx) => new {key = k, value = values[idx]})
      .ToDictionary(x => key, y => value);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM