Finding the string from the list of array objects
Because the question is about performance and efficiency that's why some sort of benchmarking would be essential to compare different implementations. I have found BenckmarkDotNet really useful for these kind of experiments. 

You can define the for loop version as your baseline and the tool will compare the other implementation against that. Here is my simplified example how to setup your environment for measurement:

[HtmlExporter]
[MemoryDiagnoser]
[SimpleJob(BenchmarkDotNet.Engines.RunStrategy.ColdStart, targetCount: 100)]
public class IterationOptimalizationExperiment
{
    private static List&lt;Data&gt; target;
    private const string TheOne = "TheOne";

    [GlobalSetup]
    public void Setup()
    {
        target = Enumerable.Range(0, 10000)
            .Select(i =&gt; new Data { Id = i, Type = i % 7777 == 0 ? TheOne : "NotTheOne" })
            .ToList();
    }

    [Benchmark(Baseline = true)]
    public void WithFor()
    {
        bool hasFound = false;
        for (int i = 0; i &lt; target.Count; i++)
            if (string.Equals(target[i].Type, TheOne, StringComparison.OrdinalIgnoreCase))
            {
                hasFound = true;
                break;
            }

    }

    [Benchmark]
    public void WithForEach()
    {
        bool hasFound = false;
        foreach (var t in target)
            if (string.Equals(t.Type, TheOne, StringComparison.OrdinalIgnoreCase))
            {
                hasFound = true;
                break;
            }
    }

    [Benchmark]
    public void WithAny()
    {
        bool hasFound = target.Any(t =&gt; string.Equals(t.Type, TheOne, StringComparison.OrdinalIgnoreCase));
    }
}


And you should simply call the following command to start your experiment: BenchmarkRunner.Run&lt;IterationOptimalizationExperiment&gt;();

When you run it in Release mode it will dump something like this: