I can't use System.Linq functions

I am trying to write this code.

FindObjectsOfType<Example>().First();

But it won’t let me import the System.Linq so I can use it.
Please don’t tell me to look around. I have been googling this for three hours; I am frustrated and just want a straight answer I can understand. It seems like I need .net framework 3.5 or above but I don’t know how to download one of those.

Have you added using System.Linq; in your script? Also FindObjectsOfType returns an array so you can just use [0] anyway.

Unity uses newer releases than that.

Actually yeah I did try using that and it didn’t work. Let me go back to the tutorial I was watching and make sure I’m using the right find objects choice because you’re right that one’s in a array it’s supposed to be a single object.
Also my project settings was set to net framework 2.5 or something and the only other option was just NET framework which I read somewhere is NET framework four just renamed but when I try it nothing happened to improve the situation.

Here’s the code I just threw together in Unity that works.

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Foo : MonoBehaviour
{
    private void Start()
    {
        var result = FindObjectsOfType<Example>().First();
        Debug.Log(result);
    }
}

9806277--1408053--upload_2024-4-30_19-59-11.png

9806277--1408056--upload_2024-4-30_19-59-39.png

There are three .NET naming and versioning schemes (thanks Microsoft): .NET Framework (maximum version 4.8), .NET Standard (maximum version 2.1), and .NET (sometimes called .NET Core that is currently up to 8.0). These are in order of their release so .NET Standard 2.1 is newer than .NET Framework 4.8.

Unity supports .NET Framework 4.8 and .NET Standard 2.1 and they’re working on adding support for the newer .NET. You can’t upgrade these yourself so if you need the latest just select .NET Standard 2.1 (it’s the default with recent releases of Unity).

LINQ was added with .NET Framework 3.5 as you saw so it’s been supported for years and it should be working.

Okay so that leads me to conclude that it must be something wrong with the code I did because that’s the version I was using originally. I’m going to go back to the tutorial and really look through it. The problem is I’m in dire need of glasses so it’s not surprising if I misread something the guy did.

Are you sure you didn’t type:

FindObjectOfType<Example>().First();

note the lack of an ‘s’ on Object

Cause this wouldn’t work since it returns a single object rather than an array.

With that said… why not use this method and avoid the array allocation if you just want the first. That’s what this would effectively do:

I suggest this because I just attempted to recreate and since I really like letting auto-complete do my typing for me I allowed it to do so after just typing FindO and it filled out without the ‘s’. And first I was like “OH, I recreated it!” but then readjusted my glasses and was like “oh… hrmmm, maybe this is OPs problem.”

Speaking of that method I noticed while testing my earlier post that it’s now marked as obsolete and you get a warning message to use one of these depending on whether you use the single or array variant.

https://docs.unity3d.com/ScriptReference/Object.FindAnyObjectByType.html
https://docs.unity3d.com/ScriptReference/Object.FindFirstObjectByType.html
https://docs.unity3d.com/ScriptReference/Object.FindObjectsByType.html

Apart from all those points, why using Linq in this case? The method First will throw an exception if the collection is null or empty. So it has absolute no benefit over:

FindObjectsOfType<Example>()[0];

which is equally dangerous but doesn’t require Linq which would allocate additional garbage. The only reason to use Linq in such a case would be when using FirstOrDefault which doesn’t throw an exception when the collection is empty but simply returns null in this case.

Though as lordofduct already mentioned, you could use FindObjectOfType instead which already returns just the first instance.

To be fair, this is First:

        [__DynamicallyInvokable]
        public static TSource First<TSource>(this IEnumerable<TSource> source)
        {
            if (source == null)
            {
                throw Error.ArgumentNull("source");
            }

            IList<TSource> list = source as IList<TSource>;
            if (list != null)
            {
                if (list.Count > 0)
                {
                    return list[0];
                }
            }
            else
            {
                using IEnumerator<TSource> enumerator = source.GetEnumerator();
                if (enumerator.MoveNext())
                {
                    return enumerator.Current;
                }
            }

            throw Error.NoElements();
        }

Since arrays of T[ ] are IList's it won’t actually allocate any garbage (aside from the garbage allocated by FindObjectsOfType which is independent of linq).

Though that is a lot more work than to just do the [0] considering that’s what it’s going to end up doing after a bunch of casting and branching.

If you were to use a collection that doesn’t implement IList then there will be an allocation for the GetEnumerator call regardless of if GetEnumerator for your collection returns it as a struct since it has to box into an IEnumerator.

note - most built in collections always implement their enumerator as a struct to avoid this allocation when handled directly rather than polymorphically like in linq. As you can see here for HashSet (unorderd collection so therefore not a IList):

also, a little bit of old trivia… in older versions of unity the compiler that used to be used translated foreach (which is just syntax sugar) to logic that called GetEnumerator casted as IEnumerator and not the collection’s Enumerator struct directly meaning it did a GC allocation for the boxing. You may trip over outdated tutorials or even just people stuck in a habit saying to use for loops or to manually do a while loop on the enumerator returned from GetEnumerator. But new versions of Unity properly compile foreach loops these days.