2009-11-24 4 views
1

В настоящее время у меня есть немного дилемма дизайна. У меня есть абстрактный класс Firmware, который обрабатывает передачу файлов (обновление прошивки) и некоторые другие вещи, такие как версия.Создание класса указателей плохая идея? (C#)

Проблема в том, что я хочу обновить пути к файлам всех MyFirmware s во всех Device s, которые у меня есть. Один из способов сделать это - иметь статический список Device s в Device, который я перебираю по обновлению Device.FilePath, всякий раз, когда я устанавливаю FirmwareFilePath или получаю событие от Firmware, что это FilePath, изменилось, не забудьте очистить их так далее.

** Edit - сделал этот пример более полной *

public class Firmware 
{ 
    private string _path; 
    public string Path 
    { 
     get { return _path; } 
     set 
     { 
      if (_path == value) 
       return; 

      _path = value; 

      OnPropertyChanged("Path"); 
     } 
    } 
} 

public class Device 
{ 
    private static readonly List<Device> _Bars = new List<Device>(); 

    private readonly Firmware _myFirmware = new Firmware() ; 
    public Firmware MyFirmware 
    { 
     get { return _myFirmware; } 
    } 

    public Device() 
    { 
     _Bars.Add(this); 
     Firmware.PropertyChanged += NewPath; 

    } 

    private void NewPath (object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "Path") 
     { 
      foreach (var dev in _Bars) 
       dev.MyFirmware.Path = MyFirmware.Path; 
     } 
    } 

} 

Или я мог бы использовать "указатель", изменить Getter, сеттер и CTOR немного.

public class Pointer<TField> 
{ 
    private TField _backingField; 

    public TField GetValue() 
    { 
    return _backingField; 
    } 

    public void SetValue(TField value) 
    { 
    _backingField = value; 
    } 
} 

public class Firmware 
{ 
    private Pointer<string> _pPath; 
    public string Path 
    { 
    get { return _pPath.GetValue(); } 
    set { _pPath.SetValue(value); } 
    } 

    public Firmware (Pointer<String> pPath) 
    { 
    _pPath = pPath; 
    } 
} 

public class Device 
{ 
    private static readonly Pointer<String> _PPath = new Pointer<string>(); 
    public static string Path 
    { 
    get { return _PPath.GetValue(); } 
    set { _PPath.SetValue(value); } 
    } 

    private readonly Firmware _myFirmware = new Firmware(_PPath); 
    public Firmware MyFirmware 
    { 
    get { return _myDevice; } 
    } 
} 

Есть ли согласованная причина, почему это было бы плохой практикой? Есть ли какая-либо ГК-ловушка, которую я не заметил?

+2

Ваше описание того, что вы хотите сделать, было бы более ясным, если бы оно было более конкретным, чем просто «foo» и «bar». Как бы то ни было, трудно понять, что вы делаете. Интуитивно, я думаю, вам просто нужна коллекция этих объектов. –

+1

Согласовано. Foo, Bar и Baz являются порождениями дьявола :) – cwap

+0

Я думаю, что у меня есть все :) –

ответ

1

Почему? Как бы я ни следовал, вы хотите сохранить экземпляр своего класса указателей на кучу объектов, разбросанных по всему месту, чтобы все они имели «указатель» на ваш один главный объект и если вы обновляете свой основной объект , все родительские классы также будут обновлены.

У меня есть несколько вопросов:

  1. если Bar имеет Foo элемент, и Foo имеет FilePath, почему Bar есть FooFilePath? В любое время вам нужно FooFilePath, почему бы не использовать MyFoo.FilePath? И почему FooFilePath статический?
  2. В вашем втором примере вместо каждого Bar, имеющего MyFoo, у него есть указатель - это единственное, что вы изменили. У указателя есть только член, который служит для того, чтобы использовать Foo.FilePath. Так почему?
  3. Если вы только общий экземпляр Foo со всеми экземплярами Bar, и вы изменили значение Foo.FilePath, и убедились, что вместо того, чтобы использовать Bar.FooFilePath все пользователи использовали Bar.MyFoo.FilePath, а затем, если вы измените значение FilePath на том, что общий Foo экземпляр, каждый экземпляр Bar автоматически получит новое значение, без необходимости проходить через эти обручи.

Проблема не в том, что ваше решение не сработает, а скорее, что это не нужно.

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

+0

1) Так как это фактическое значение сохраняется, когда оно статично, потому что все MyFirmware на определенном типе устройства должны иметь тот же FilePath. 2) Я не уверен, что понимаю, у каждого устройства все еще есть прошивка, и, как вы говорите, теперь есть указатель. 3) Объекты прошивки содержат больше данных, чем просто FilePath - это мешает мне использовать один и тот же объект Firmware. –

+0

А, это немного сообщает об этом. Это подводные камни создания игрушечных примеров, которые не полностью отображают реальную архитектуру. См. Мое редактирование. – Dathan

0

Нет, я не вижу никаких ловушек GC, и ваше решение кажется полным, хотя немного странным. Для чего нужен указатель? То, что вы действительно ищете, является ссылкой, если вы изменяете свойства ссылочного объекта, все ссылки также будут обновлены.

Если вы хотите сменить объект объекта (что может быть так), я думаю, ваше решение кажется правильным.

+0

Да Я пытаюсь изменить все экземпляры Firmware, принадлежащие любому объекту устройства. –

+0

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

Смежные вопросы