Как назначить объекту ссылки

У меня есть два списка объектов

 [Serializable]
 private class MemorySet
 {
    public Dictionary<string, object> _Map;
    public List<object> _Results;
    public List<object> _Storage;
 }
 MemorySet Memory = new MemorySet();

Мне могут быть назначены ключи для объекта, например

    _Map.Add("someKey", _Results[_Results.Count - 1]);

У меня есть метод

private object Mapper(string key)
{
    if (Memory._Map.ContainsKey(key))
    {
        return Memory._Map[key];
    }
    else if (key.ToLower() == "result")
    {
        return Memory._Results[Memory._Results.Count - 1];
    }
    else if (key.ToLower() == "storage")
    {
        return Memory._Storage[Memory._Storage.Count - 1];
    }
    else if (key.ToLower().Contains("result"))
    {
        int n = Convert.ToInt32(key.ToLower().Split(new string[] { "result" }, StringSplitOptions.None)[1]);
        return Memory._Results[n];
    }
    else if (key.ToLower().Contains("storage"))
    {
        int n = Convert.ToInt32(key.ToLower().Split(new string[] { "storage" }, StringSplitOptions.None)[1]);
        return Memory._Storage[n];
    }
    else return null;
}

Теперь я должен назначить объекту из _Storage или _Results, как это:

object obj = key != "" ? Mapper(key) : Memory._Storage[Memory._Storage.Count - 1];
if(obj is string) obj as string = "test";

это изменит obj для ссылки на новую строку в памяти. Но вместо этого я хочу изменить объект, на который ссылается obj.

Другими словами, obj станет «тестовым», но базовый объект не будет изменен.

Я понимаю, почему это происходит, хотя я не представлял себе это таким образом, когда писал весь двигатель, и теперь у меня большие проблемы с этим. В C++ у нас есть указатели, но в C# я не хочу использовать GCHandles или неуправляемый код для этой тривиальной вещи, было бы крайне некрасиво.

Итак, как назначить объекту, на который указывает объект, вместо того, чтобы назначать самому объекту?

Метки

2 ответа

  1. Попробовать это

    [Serializable]
        private class MemorySet
        {
            public Dictionary<string, object> _Map = new Dictionary<string,object>();
            public List<object> _Results = new List<object>();
            public List<object> _Storage = new List<object>)_;
        }
    
  2. Если вы не хотите связываться с текущим дизайном, вы можете просто добавить метод, который обновит ваши структуры данных на том же шаблоне, что и ваш Mapperметод. Вот как это будет выглядеть:

    private void Update(string key, object value)
    {
      if (Memory._Map.ContainsKey(key))
      {
        Memory._Map[key] = value;
      }
      else if (key.ToLower() == "result")
      {
        Memory._Results[Memory._Results.Count - 1] = value;
      }
      else if (key.ToLower() == "storage")
      {
        Memory._Storage[Memory._Storage.Count - 1] = value;
      }
      else if (key.ToLower().Contains("result"))
      {
        int n = Convert.ToInt32(key.ToLower().Split(new string[] { "result" }, StringSplitOptions.None)[1]);
        Memory._Results[n] = value;
      }
      else if (key.ToLower().Contains("storage"))
      {
        int n = Convert.ToInt32(key.ToLower().Split(new string[] { "storage" }, StringSplitOptions.None)[1]);
        Memory._Storage[n] = value;
      }
      else
      {
        throw new ArgumentException("Failed to compute valid mapping", nameof(key));
      }
    }
    

    Возможно, вы также можете добавить key == ""шаблон там, я не уверен, что понимаю, как это будет использоваться точно, но надеюсь, вы получите идею.

    EDIT: OK, поэтому ссылки на один и тот же объект используются в разных структурах. Вы должны рассмотреть вопрос о разработкеMemorySet, которая позволяет избежать этого. Если вы все еще думаете, что это правильный дизайн, учитывающий ваши потребности, у вас есть простое решение: оберните ваши целевые объекты в другие объекты.

    public class ObjectWrapper
    {
      public object ObjectOfInterest { get; set; }
    }
    

    Теперь вы храните ObjectWrapperобъекты. Затем можно обновить свойствоObjectOfInterest, и это изменение будет отражено во всех структурах, которые содержат это ObjectWrapper:

    ObjectWrapper wrapper = Mapper(key);
    wrapper.ObjectOfInterest = "test";