Самый простой вариант - объявить CellPos как record:
public record struct CellPos(int X, int Y); //record struct, тк объект маленький и очень похож на value-object
Тогда его можно будет использовать как ключ в словаре.
Чуть сложнее вариант, или если ты используешь старую версию языка и рантайма (очень советую обновиться, если возможно):
Самому добавить методы GetHashCode и Equals.
Про то, как они должны работать, читай тут:
https://docs.microsoft.com/en-us/dotnet/api/system...
Вариант три, если не можешь никак трогать CellPos - создай новый класс, который будет реализовывать интерфейс
System.Collections.Generic.IEqualityComparer<CellPos> и передавай его в словарь (там параметр есть)