Search Unity

Using System.Linq automatically without using directive?

Discussion in 'Scripting' started by Tristan-Moore, Sep 6, 2014.

  1. Tristan-Moore

    Tristan-Moore

    Joined:
    Aug 22, 2014
    Posts:
    18
    So this is a strange question. I'm a designer and not a career programmer, so a lot of my code knowledge has been based on exploration of Unity itself. I've often used a public array of strings in a trigger script, then used a simple line like this to check if the trigger behavior should execute:

    Code (CSharp):
    1.     public String[] validTags;
    2.    
    3.     void OnTriggerEnter(Collider other)
    4.     {
    5.         if (validTags.Contains (other.collider.tag))
    6.         {
    7.             //behavior goes here
    8.         }
    9.     }
    To my knowledge this was built-in behavior for UnityEngine or System.Collections. However, I grabbed an update to an asset on the asset store and had to delete it, only after I did I found that all of my script files that used the above snippet were returning an error:

    Type `string[]' does not contain a definition for `Contains' and no extension method `Contains' of type `string[]' could be found (are you missing a using directive or an assembly reference?)

    After this happened, I found out I should actually be using System.Linq to get this functionality. So why didn't I have to type this in before? I've been working on this particular project for months and non of the other developers had this sudden issue; all the code still works without using System.Linq, its only on my machine that it's required. I don't want to commit to the depot until I understand what has happened or what the proper practice should be. Can anyone explain what I'm missing here? Thanks.
     
  2. Graph

    Graph

    Joined:
    Jun 8, 2014
    Posts:
    154
    To use the language integrated query extension methods you do need to include them (add a using statement), that is the correct thing to do.

    The asset may have had a static class containing it's own extensions to the IEnumerable derivations to implement a Contains method.

    You can implement your own ones quite easily into the global scope (no namespace)..
    Here are a few examples:

    Code (CSharp):
    1.  
    2. #region usings
    3. using System;
    4. using System.Collections.Generic;
    5. using System.Linq;
    6. using System.Text;
    7. using System.Collections;
    8. using System.Xml.Serialization;
    9. using System.IO;
    10. using System.Runtime.Serialization.Formatters.Binary;
    11. using System.Diagnostics;
    12. #endregion
    13.  
    14. public static class Extensions
    15. {
    16.   private static Random rnd = new Random();
    17.  
    18.   #region <Templated>
    19.  
    20.   /// <summary>
    21.   /// Finds the number of Differences between this and obj  
    22.   /// {1, 2, 3, 4, 5} and {1, 5, 3, 4, 2} would have a Distance of 2
    23.   /// </summary>
    24.   /// <param name="value"></param>
    25.   /// <param name="second">the object to compare to</param>
    26.   /// <returns>Number of Differences</returns>
    27.   public static int Distance<TSource>(this TSource[] value, TSource[] second)
    28.     where TSource : IEquatable<TSource>
    29.   {
    30.     int diff = 0;
    31.     for (int i = 0; i < second.Length; i++)
    32.     {
    33.       if (!value[i].Equals(second[i]))
    34.         diff++;
    35.     }
    36.  
    37.     return diff;
    38.   }
    39.  
    40.  
    41.   #region [].Copy()
    42.  
    43.   /// <summary>
    44.   /// Returns a new copy of this array
    45.   /// </summary>
    46.   /// <typeparam name="TSource"></typeparam>
    47.   /// <param name="source"></param>
    48.   /// <returns></returns>
    49.   public static TSource[] Copy<TSource>(this TSource[] source)
    50.   {
    51.     var arr = new TSource[source.Length];
    52.     source.CopyTo(arr, 0);
    53.     return arr;
    54.   }
    55.  
    56.   /// <summary>
    57.   /// Copies n items from this array into a new one; from start for n
    58.   /// </summary>
    59.   /// <typeparam name="TSource"></typeparam>
    60.   /// <param name="source"></param>
    61.   /// <param name="start"></param>
    62.   /// <param name="n"></param>
    63.   /// <returns></returns>
    64.   public static TSource[] Copy<TSource>(this TSource[] source, int start, int n)
    65.   {
    66.     var arr = new TSource[n];
    67.  
    68.     uint ind = 0;
    69.     for (int i = start; i < start + n; i++)
    70.     {
    71.       arr[ind] = source[i];
    72.       ind++;
    73.     }
    74.     return arr;
    75.   }
    76.  
    77.   #endregion
    78.  
    79.   #region ICollection.Add()
    80.  
    81.   /// <summary>
    82.   /// Adds a collection of items to this collection
    83.   /// </summary>
    84.   /// <typeparam name="TSource"></typeparam>
    85.   /// <typeparam name="S"></typeparam>
    86.   /// <param name="list"></param>
    87.   /// <param name="values"></param>
    88.   public static void AddRange<TSource, S>(this ICollection<TSource> list, params S[] values)
    89.     where S : TSource
    90.   {
    91.     foreach (S value in values)
    92.       list.Add(value);
    93.   }
    94.  
    95.   /// <summary>
    96.   /// Adds an item to the collection, but only if it's not already present
    97.   /// </summary>
    98.   /// <typeparam name="TSource"></typeparam>
    99.   /// <typeparam name="S"></typeparam>
    100.   /// <param name="list"></param>
    101.   /// <param name="value"></param>
    102.   public static void AddIfUnique<TSource, S>(this ICollection<TSource> list, S value)
    103.     where S : TSource
    104.   {
    105.     if (!list.Contains(value))
    106.       list.Add(value);
    107.   }
    108.  
    109.   /// <summary>
    110.   /// Adds a set of items to the collection, but only if an item isn't already present
    111.   /// </summary>
    112.   /// <typeparam name="TSource"></typeparam>
    113.   /// <typeparam name="S"></typeparam>
    114.   /// <param name="list"></param>
    115.   /// <param name="values"></param>
    116.   public static void AddIfUnique<TSource, S>(this ICollection<TSource> list, params S[] values)
    117.     where S : TSource
    118.   {
    119.     foreach (S value in values)
    120.       if (!list.Contains(value))
    121.         list.Add(value);
    122.   }
    123.  
    124.   /// <summary>
    125.   /// Shuffles a set by seed value
    126.   /// </summary>
    127.   /// <typeparam name="TSource"></typeparam>
    128.   /// <param name="list"></param>
    129.   /// <param name="seed"></param>
    130.   /// <returns></returns>
    131.   public static IEnumerable Shuffle<TSource>(this IEnumerable<TSource> list, int seed)
    132.   {
    133.     Random rnd = new Random(seed);
    134.  
    135.     return list.OrderBy(p => rnd.Next(100)); ;
    136.   }
    137.  
    138.   /// <summary>
    139.   /// Shuffles a set randomly
    140.   /// </summary>
    141.   /// <typeparam name="TSource"></typeparam>
    142.   /// <param name="list"></param>
    143.   /// <returns></returns>
    144.   public static IEnumerable<TSource> Shuffle<TSource>(this IEnumerable<TSource> list)
    145.   {
    146.     return list.OrderBy(p => rnd.Next(100)); ;
    147.   }
    148.  
    149.  
    150.  
    151.   #endregion
    152.  
    153.   #region IEnumerable.ForEach()
    154.  
    155.   /// <summary>
    156.   ///
    157.   /// </summary>
    158.   /// <typeparam name="TSource"></typeparam>
    159.   /// <param name="enum"></param>
    160.   /// <param name="mapFunction"></param>
    161.   public static void ForEach<TSource>(this IEnumerable<TSource> @enum, Action<TSource> mapFunction)
    162.   {
    163.     foreach (var item in @enum) mapFunction(item);
    164.   }
    165.  
    166.   #endregion
    167.  
    168.   public static T To<T>(this IConvertible obj)
    169.   {
    170.     return (T)Convert.ChangeType(obj, typeof(T));
    171.   }
    172.  
    173.   [DebuggerStepThrough()]
    174.   public static bool Is<T>(this object item) where T : class
    175.   {
    176.     return item is T;
    177.   }
    178.  
    179.   [DebuggerStepThrough()]
    180.   public static bool IsNot<T>(this object item) where T : class
    181.   {
    182.     return !(item.Is<T>());
    183.   }
    184.  
    185.   [DebuggerStepThrough()]
    186.   public static T As<T>(this object item) where T : class
    187.   {
    188.     return item as T;
    189.   }
    190.  
    191.  
    192.  
    193.   #endregion
    194.  
    195. }
    196.  
    197.  
     
  3. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    'Contains' has never been a part of T[] arrays
    It IS, however, a part of List<T> generic lists.
    You sure you weren't using generic list before?
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532