String de-duplication using a custom string pool
So, you want a Collection which should hold your strings. The easiest and fastest would be to simply use an array. So let us do it.  

Because you are using this for pooling strings, we we only need a string[] array. We should add a method bool TryGetValue(string key, out string value) and a string Add(string value).  

If we use an array we need to initialize this array to a given capacity at the constructor level and add a possibility to let the array grow if needed.  

I decided to use the name you want CoolClass but it should be better named to something more meaningful.  

We need to check if a given "key" is in the array at two places, the TryGetValue() and the Add() method. So let us introduce another method int IndexOf(string key) which returns the index of the given keyand if it isn't in the array it returns -1, which should be extracted to a const.

This leads to  

public class CoolClass
{
    private string[] array;
    private int capacity;
    private int lastElement = -1;
    private const int elementNotFound = -1;

    public CoolClass() : this(1024) { }
    public CoolClass(int capacity)
    {
        this.capacity = capacity;
        array = new string[capacity];
    }

    public bool TryGetValue(string key, out string value)
    {
        int i;
        if ((i = IndexOf(key)) != elementNotFound)
        {
            value = array[i];
            return true;
        }

        value = null;
        return false;
    }

    public void Add(String value)
    {
        if (value != null)
        {
            int i;
            if ((i = IndexOf(value)) != elementNotFound)
            {
                lastElement++;
                if (lastElement &gt;= capacity)
                {
                    Grow();
                }
                array[lastElement] = value;
            }
        }
    }

    private int IndexOf(string key)
    {
        for (int i = 0; i &lt; lastElement; i++)
        {
            if (array[i] == key)
            {
                return i;
            }
        }
        return elementNotFound;
    }

    private void Grow()
    {
        capacity = capacity * 2;
        Array.Resize(ref array, capacity);

    }
}  


But maybe we should think about this. Why shouldn't we rename the TryGetValue() to GetOrAdd() and remove the Add() method  ? Because we don't want to handle cases where the string isn't pooled in the client code.  

public class CoolClass
{
    private string[] array;
    private int capacity;
    private int lastElement = -1;
    private const int elementNotFound = -1;

    public CoolClass() : this(1024) { }
    public CoolClass(int capacity)
    {
        this.capacity = capacity;
        array = new string[capacity];
    }

    public string GetOrAdd(string key)
    {
        if (key == null) { return null; }

        int i;
        if ((i = IndexOf(key)) != elementNotFound)
        {
            return array[i];
        }

        lastElement++;
        if (lastElement &gt;= capacity)
        {
            Grow();
        }

        array[lastElement] = key;
        return array[lastElement];

    }

    private int IndexOf(string key)
    {
        for (int i = 0; i &lt; lastElement; i++)
        {
            if (array[i] == key)
            {
                return i;
            }
        }
        return elementNotFound;
    }

    private void Grow()
    {
        capacity = capacity * 2;
        Array.Resize(ref array, capacity);

    }
}




You reallay should use braces {} for singleline if statements too, this won't harm but makes the code less error prone.  



Also it isn't mentioned explicitly in the naming guidelines how to name internal static variables, you should use camelCase casing for naming them.  



By using a guard clause like  

if (string.IsNullOrEmpty(value) || value.Length &gt; 200) { return value; }  


you can return early and therefor you save horizontal spacing which improves the readability of the code.