Могу ли я использовать коллекцию C # для хранения экземпляров классов с самоссылочными отношениями? - PullRequest
2 голосов
/ 06 октября 2009

Мне нужно смоделировать в памяти коллекцию веб-файлов, но это отношения между ними. То есть файл A (например, html) может иметь ссылку на файл B (например, css) и файл C (например, javascript). Также для файла D может также потребоваться файл B. Если бы я хотел удалить файл A, мне нужно было бы убедиться, что любые файлы, которые он использует (например, файл B), также не используются другим файлом (например, файл D). Возможно что-то вроде:

  List<WebFile> list_of_webfiles

  public class WebFile
  - string url
  - bool parentFile

  public class FileRelationship
  - private WebFile parentWebFile;
  - private WebFile childWebFile;

ВОПРОС - Как лучше всего смоделировать это в C #? (например, какой тип коллекции и как моделировать)

Примечание - он должен быть смоделирован в памяти (без базы данных), и мне нужно иметь возможность сериализации в XML для сохранения. Примером того, что я имею в виду, было бы нечто, похожее на это ...

        XmlSerializer serializer = new XmlSerializer(typeof(List<WebFile>));
        TextWriter textWriter = new StreamWriter(CONFIG_FILE_PATH);
        serializer.Serialize(textWriter,  list_of_webfiles);
        textWriter.Close();

Спасибо

Ответы [ 2 ]

1 голос
/ 06 октября 2009

Тот факт, что у вас есть дубликаты (с точки зрения нескольких файлов, требующих B), означает, что было бы затруднительно использовать наиболее очевидную структуру «требует» в виде дерева, поскольку это потребовало бы многократного вложения B (от разных родителей). ). Несколько вариантов:

  • сохранить объектные ссылки в объектной модели, но только перечислить имя (или некоторую другую ссылку) в файле; сравнительно просто сделать, но требует исправлений после десериализации
  • перечисляет только имя (или некоторую другую ссылку) в отношении, и отражает его в объектной модели - т.е. "file.Parent" - это ключ, а не другой объект
  • имеет полную объектную модель и использует сериализатор графа, такой как DataContractSerializer с включенными preserve-object-reference

Я бы, наверное, выбрал между двумя последними; последний имеет «не очень красивый» XML, но относительно прост в реализации. Но я бы соблазнился просто использовать средний параметр и иметь только ключевые ссылки в объектной модели, т.е.

[XmlType("file"), XmlRoot("file")]
public class File {
    [XmlAttribute("name")]
    public string Name {get;set;}
    [XmlElement("ref")]
    public List<string> References {get;set;}
    public File() {References = new List<string>();}
}

может быть, не чистый ОО, но просто сделать. Также - избегайте необходимости дублировать данные; если вы храните его точно так же, как описано выше, вы всегда можете отсканировать, чтобы увидеть «что использует этот файл» (с некоторой индексацией, если вам нужно). Но пытаться поддерживать отношения в обоих направлениях (т. Е. «UsedBy») - это кошмар.

1 голос
/ 06 октября 2009

Это, кажется, подразумевает иерархические «древовидные» отношения, где вы можете иметь

Class WebFile:
- URL : string
- Parent : WebFile
- Children : WebFile[] (could be a list depending on the need)

Тогда где-то у вас есть

List<WebFile> webFiles;

Этот подход облегчает обход дерева веб-файлов и поиск связанных, но сложнее перечислить все файлы сами.

Кроме того, вы можете хранить список файлов и отношений отдельно

Class WebFile
- URL : string

Class WebFileRelationship
- Parent : WebFile
- Child : WebFile

И у вас есть 2 контейнера

List<WebFile> webFiles;
List<WebFileRelationship> relationships;

Этот подход позволяет легко перечислить все отношения или все файлы, но сложно определить отдельные отношения.

Все зависит от вашего приложения, вам нужна дополнительная информация об отдельных файлах или отношениях?

...