Как преобразовать тип проекта в тип библиотеки общего класса

2

(Образцы кода С# находятся в нижней части вопроса.)

У меня есть библиотека классов, разделяемая между несколькими решениями, с типом SharedType. У меня есть метод в библиотеке классов, который обрабатывает коллекцию этого типа:

Sub ProcessSharedTypeEnumerable(src As IEnumerable(Of SharedType))
    'do something here
End Sub

Каждое решение имеет свой собственный специфический тип, который должен отображать/преобразовывать в SharedType:

Namespace Project1
    Class ProjectType
    End Class
End Namespace

Как я могу вызвать ProcessSharedTypeEnumerable без необходимости конвертировать ProjectType в SharedType на сайт вызова?

Dim lst As New List(Of ProjectType)
'populate list

'instead of this:
ProcessSharedTypeEnumerable(lst.Select(Function(x) New SharedType With { 'populate members here' })
'use this:
ProcessSharedTypeEnumerable(lst)

Я знаю, что у меня может быть тип проекта, реализующий интерфейс из библиотеки классов, который имеет метод, который сопоставляется с общим типом

Public Interface ISharedTypeMappable
    Function ToSharedType() As SharedType
End Interface

Тогда метод ProcessSharedTypeEnumerable может принимать IEnumerable(Of ISharedTypeMappable) и я могу вызвать .Select(Function(x) x.ToSharedType) в ProcessSharedTypeEnumerable чтобы получить IEnumerable(Of SharedType).


Есть ли более "правильный" способ сделать это? Общая ковариация и неявное преобразование? Некоторые встроенные механизмы преобразования.NET?


Примеры кода С#

Метод библиотеки классов:

static class Utils { //I know it an awful name ...
    static void ProcessSharedTypeEnumerable(IEnumerable<SharedType> src) {
        //do something here
    }
}

Код проекта:

var lst = new List<ProjectType>();
//populate list

//instead of this:
Utils.ProcessSharedTypeEnumerable(lst.Select(x=>new SharedType { /* populate properties here */}));
//do this
Utils.ProcessSharedTypeEnumerable(lst);

Обновить

Я не хочу наследовать ProjectType из SharedType по двум причинам (1) ProjectType уже наследуется от другого базового типа, и (2) SharedType может иметь членов, которые не должны быть в ProjectType.

  • 1
    Если вы хотите вызвать этот метод, вы должны фактически передать его, что он ожидает. Вы должны передать ему список объектов, которые являются SharedType . Таким образом, либо SharedType должен быть классом, унаследованным от ProjectType либо это должен быть интерфейс, который реализован в ProjectType .
  • 0
    @jmcilhinney ... или ProjectType может реализовать интерфейс, который имеет метод для сопоставления с SharedType , а ProcessSharedTypeEnumerable может взять IEnumerable указанного интерфейса и использовать метод интерфейса для проецирования в IEnumerable(Of SharedType) . Как я уже писал во втором разделе.
Показать ещё 4 комментария
Теги:
mapping

2 ответа

0

EDIT: теперь это ответ сообщества wiki

В соответствии с просьбой, здесь была моя попытка реализовать Operator Widening CType. Однако это не сработает. Может быть, кто-то, кто это читает, может это исправить.

Module Module1

  Sub Main()
    Dim lst As New List(Of ProjectType) From {
        New ProjectType With {.t = "1"},
        New ProjectType With {.t = "2"},
        New ProjectType With {.t = "3"}
    }
    MsgBox(CType(lst(0), SharedType).s) 'This works'
    ProcessSharedTypeEnumerable(lst) 'This does not :-( '
    ProcessSharedTypeEnumerable(lst.Cast(Of SharedType).ToList) 'Neither does this :-( '
  End Sub

  Sub ProcessSharedTypeEnumerable(src As IEnumerable(Of SharedType))
    For Each st As SharedType In src
      MsgBox(st.s)
    Next st
  End Sub

  Class SharedType
    Property s As String
  End Class

  Class ProjectType
    Property t As String

    Public Shared Widening Operator CType(p As ProjectType) As SharedType
      Return New SharedType With {.s = p.t}
    End Operator
  End Class
End Module
  • 0
    На самом деле, это не будет работать, если ProcessSharedTypeEnumerable изменяет свойства любого из объектов ProjectType в списке. Я думаю, что вам придется поставить в функции конвертера
0

Наследование?

Sub Main()
    Dim lst As New List(Of ProjectType) From {
        New ProjectType With {.s = "1"},
        New ProjectType With {.s = "2"},
        New ProjectType With {.s = "3"}
    }
    SharedType.ProcessSharedTypeEnumerable(lst)
End Sub

Shared Sub ProcessSharedTypeEnumerable(src As IEnumerable(Of SharedType))
    For Each st As SharedType In src
        MsgBox(st.s)
    Next
End Sub

Class SharedType
    Property s As String
End Class

Class ProjectType
    Inherits SharedType
End Class
  • 0
    Это будет путь, за исключением того, что ProjectType уже имеет другой базовый класс, чем SharedType .
  • 0
    Хорошо, тогда я верну изменения. Удачи в поиске ответа.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню