В C# как я могу создать метод многократного использования, где мне нужен доступ к нескольким типам списков? - PullRequest
0 голосов
/ 01 мая 2020

У меня есть два следующих метода:

private void AddHeaderAttachment(AAttachment attachment) {
    string parentId = attachment.ParentId;
    if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
        if (!collection.AAttachmentByParentIds.TryGetValue(parentId, out List<AAttachment> attachmentList)) {
            attachmentList = new List<AAttachment>();
            collection.AAttachmentByParentIds.Add(parentId, attachmentList);
        }
        attachmentList.Add(attachment);
    }
}

private void AddLineAttachment(BAttachment attachment) {
    string parentId = attachment.ParentId;
    if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
        if (!collection.BAttachmentByParentIds.TryGetValue(parentId, out List<BAttachment> attachmentList)) {
            attachmentList = new List<BAttachment>();
            collection.BAttachmentByParentIds.Add(parentId, attachmentList);
        }
        attachmentList.Add(attachment);
    }
}

Класс MyCollection выглядит следующим образом:

 public class MyCollection {
        public Dictionary<string, List<AAttachment>> AAttachmentByParentIds = new Dictionary<string, List<AAttachment>>();
        public Dictionary<string, List<BAttachment>> BAttachmentByParentIds = new Dictionary<string, List<BAttachment>>();
}

Как видите, единственные различия между этими двумя методами выше являются:

  1. Предоставляемый тип
  2. Свойство MyCollection, к которому будет добавлено вложение.

Однако оба AAttachment и BAttachment реализовать:

 interface Attachable {
    string ParentId { get; }
 }

Я хотел бы создать один метод многократного использования.

Но у меня есть две очевидные проблемы:

  1. Если я изменю внутренняя if в:
                if (!collection.AAttachmentByParentIds.TryGetValue(parentId, out List<Attachable> attachmentList)) {
                    attachmentList = new List<Attachable>();
                    collection.lineAttachmentByParentIds.Add(parentId, attachmentList);
                }

Visual Studio сообщает мне «Аргумент 2: невозможно преобразовать out List<Attachable> в out List<AttachmentA>

и

Как я могу изменить, ссылаюсь ли я AAttachmentByParentIds или BAttachmentByParentIds на экземпляр MyCollection?

Ответы [ 2 ]

2 голосов
/ 01 мая 2020

Вы хотите использовать дженерики:

private void AddHeaderAttachment<TAttachment>(
    Func<MyCollection, Dictionary<string, List<TAttachment>>> attachmentByParentIdsSelector,
    TAttachment attachment) where TAttachment : Attachable
{
    string parentId = attachment.ParentId;
    if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection))
    {
        var attachmentByParentIds = attachmentByParentIdsSelector(collection);
        if (!attachmentByParentIds.TryGetValue(parentId, out List<TAttachment> attachmentList))
        {
            attachmentList = new List<TAttachment>();
            attachmentByParentIds.Add(parentId, attachmentList);
        }
        attachmentList.Add(attachment);
    }
}

private void AddHeaderAttachment(AAttachment attachment) 
{
    AddHeaderAttachment(x => x.AAttachmentByParentIds, attachment);
}

private void AddHeaderAttachment(BAttachment attachment) 
{
    AddHeaderAttachment(x => x.BAttachmentByParentIds, attachment);
}
2 голосов
/ 01 мая 2020

Вы пытались использовать генерики :

private void AddAttachable<T>(....) where T:Attachable 

полный код, который выглядит примерно так:

private void AddAttachable<T>(T attachment, Func<MyCollection, Dictionary<string,T>> getFunc) 
     where T:Attachable  
{
string parentId = attachment.ParentId;
if (this.collectionByIds.TryGetValue(attachment.Id, out MyCollection collection)) {
    // func is used here
    if (!getFunc(collection).TryGetValue(parentId, out List<T> attachmentList)) {
        attachmentList = new List<T>();
        // and here, can be moved to variable
        getFunc(collection).Add(parentId, attachmentList);
    }
    attachmentList.Add(attachment);
}
}

и использование

BAttachment bAttach = ...
AddAttachment(bAttach, col => col.BAttachmentByParentIds )
...