My example on how to read file in chunks:
using System;
using System.IO;
using System.Text;

namespace ReadFileInChunks
{
    class Program
    {
        static void Main(string[] args)
        {
            int lineNumber = 0;

            long beginBytes = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
            Console.WriteLine($"Bytes: {beginBytes}");
            Console.WriteLine("");
            Console.ReadKey();

            long beginMemory = GC.GetTotalMemory(true);
            Console.WriteLine($"Memory: {beginMemory}");
            Console.WriteLine("");
            Console.ReadKey();

            //string wholeFile = File.ReadAllText("test.txt");

            //Console.WriteLine("");
            //Console.WriteLine("******************");
            //Console.WriteLine("*    ReadAllText *");
            //Console.WriteLine("******************");
            //Console.WriteLine("");

            //beginBytes = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
            //Console.WriteLine($"Bytes: {beginBytes}");
            //Console.WriteLine("");
            //Console.ReadKey();

            //beginMemory = GC.GetTotalMemory(true);
            //Console.WriteLine($"Memory: {beginMemory}");
            //Console.WriteLine("");
            //Console.ReadKey();

            using (FileStream fileStream = new FileStream("test.txt", FileMode.Open, FileAccess.Read))
            {
                int count = 10000;
                byte[] buffer = new byte[count];

                int read = 1;
                while (read > 0)
                {
                    read = fileStream.Read(buffer, 0, count);
                    string partOfFile = Encoding.UTF8.GetString(buffer, 0, read);
                    using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(partOfFile)))
                    {
                        using (StreamReader streamReader = new StreamReader(memoryStream, Encoding.UTF8, true))
                        {
                            while (!streamReader.EndOfStream)
                            {
                                Console.WriteLine($"{lineNumber++}: {streamReader.ReadLine()}");
                            }
                        }
                    }
                    Console.WriteLine("");
                    Console.WriteLine("******************");
                    Console.WriteLine("*    Next block  *");
                    Console.WriteLine("******************");
                    Console.WriteLine("");

                    long bytes = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
                    Console.WriteLine($"Bytes at the beginning: {beginBytes}, current bytes: {bytes}");

                    Console.WriteLine("");
                    Console.ReadKey();

                    long memory = GC.GetTotalMemory(true);
                    Console.WriteLine($"Memory at the beginning: {beginMemory}, current memory: {memory}");
                    Console.WriteLine("");
                    Console.ReadKey();
                }
            }
            Console.WriteLine("Press any key");
            Console.ReadKey();
        }
    }
}
In order to check if a class is already contained in a List, you need to implement IEquatable.

For example, I want to have class IDName added in to list, but, I don't want to have duplicates. Class:

class IDName: IEquatable<IDName>
{
	public Guid ID { get; set; }
	public string Name { get; set; }

	public IDName (Guid id, string name)
	{
		ID = id;
		Name = name;
	}

	public bool Equals(IDName other)
	{
		return ID == other.ID && Name == other.Name;
	}
}
Program:
using System;
using System.Collections.Generic;

namespace Contains
{
	class Program
	{
		static void Main(string[] args)
		{
			List<IDName> idNames = new List<IDName>();

			Guid idFirst = Guid.NewGuid();
			IDName idNameFirst = new IDName(idFirst, "first");

			Guid idSecond = Guid.NewGuid();
			IDName idNameSecond = new IDName(idSecond, "second");

			idNames.Add(idNameFirst);
			idNames.Add(idNameSecond);

			if (idNames.Contains(idNameFirst))
			{
				Console.WriteLine("idNameFirst is already added");
			}

			Console.ReadKey();
		}
	}
}
To write this article I was using this web site.

First create JSON configuration file, in my case I did it like this:

Right click on file, and click properties:

Set "Copy to Output Directory", in my case I have set it to "Copy always":

Add following references:

Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.FileExtensions
Microsoft.Extensions.Configuration.Json

In my case I have added them with NuGet:

Or you can add them via console:

dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.FileExtensions
dotnet add package Microsoft.Extensions.Configuration.Json

In my case my JSON configuration file looks like this:

{
"apiKey":  "myApiKey"
}
Code:
using Microsoft.Extensions.Configuration;
using System;
using System.IO;

namespace jsonConfigurationFile
{
  class Program
  {
    static void Main(string[] args)
    {
      IConfiguration config = new ConfigurationBuilder()
          .AddJsonFile("jsconfig1.json", true, true)
          .Build();

      Console.WriteLine($" Key: { config["apiKey"] }");
      Console.ReadKey();
    }
  }
}
Recently I was trying to deserialize JSON which I have received from Google Reverse Geocoding (Address Lookup). First I was playing with example which is described here, but I didn't like that method, since it is too complicated. In order to deserialize JSON into an object, first I have to create that object, and in case of Google it is too complicated. Here is my partial solution, when I definitely decided to give up. I needed name of the city, and state of location:
using (JsonDocument document = JsonDocument.Parse(doc))
{
	Console.WriteLine($"plus_code: {document.RootElement.GetProperty("plus_code")}");
	foreach (JsonElement element in document.RootElement.GetProperty("results").EnumerateArray())
	{
		foreach (JsonElement addComp in element.GetProperty("address_components").EnumerateArray())
		{
			Console.WriteLine($"long_name: {addComp.GetProperty("long_name")}, short_name: {addComp.GetProperty("short_name")}");
			foreach (JsonElement type in addComp.GetProperty("types").EnumerateArray())
			{
				Console.WriteLine($"type: {type.ToString()}");
			}
		}
	}
}
I have decided to go further using this (Newtonsoft.Json) solution. Just with one line of code:
JObject myJObject = JObject.Parse(doc);
I have basically extracted everything I need.