public SomeClassThatUsesValueWithId(SerializationInfo info, StreamingContext ctxt)
    {
        string valId = (string)info.GetString("Val");
        CollectionOfValuesWithId col = ctxt.Context as CollectionOfValuesWithId;

        if (col != null)
        {
            Val = col.GetValueFromId(valId);
        }
    }
    public static void Main(string[] args)
    {
        CollectionOfValuesWithId col = new CollectionOfValuesWithId();

        col.AddValue(new ValueWithId("foo", "bar"));

        SomeClassThatUsesValueWithId sc = new SomeClassThatUsesValueWithId(col.GetValueFromId("foo"));

        BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File, col));

        using (var stream = new FileStream("foo", FileMode.Create))
        {
            bf.Serialize(stream, sc);
        }

        col.GetValueFromId("foo").ActualValue = "new value";

        using (var stream2 = new FileStream("foo", FileMode.Open))
        {
            Console.WriteLine(bf.Deserialize(stream2));
        }
    }