2015-07-22 7 views
2

(образцы C# код находятся в нижней части вопроса.)Как преобразовать тип проекта в общий класс библиотеки типа

У меня есть библиотека классов общего между количеством решений, с типом называется 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?


C# примеры кода

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

static class Utils { //I know it's 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); 

Update

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

+1

Если вы хотите назвать этот метод, вы должны фактически передать ему то, что он ожидает. Вы должны передать ему список объектов, которые ARE 'SharedType'.Таким образом, либо «SharedType» должен быть классом, который наследуется «ProjectType», либо он должен быть интерфейсом, который реализуется «ProjectType». – jmcilhinney

+0

@jmcilhinney ... или 'ProjectType' может реализовать интерфейс, который имеет способ сопоставления с' SharedType', а 'ProcessSharedTypeEnumerable' может принимать« IEnumerable »указанного интерфейса и использовать метод интерфейса для проекта в IENumerable (SharedType). Как я писал во втором разделе. –

+0

это игра в другую игру. Если параметр метода больше не вводит 'SharedType', то это не та же игра. Мой комментарий все еще стоит, т. Е. Вам нужно передать метод, которого он ожидает. Если он ожидает «IEnumerable (Of SharedType)», тогда вам нужно передать «IEnumerable (Of SharedType)», и если он ожидает «IEnumerable (Of ISharedTypeMappable)», то это то, что вам нужно передать. Кажется довольно бессмысленным, чтобы ваш 'ProjectType' реализовал некоторый hinky-интерфейс, когда вы могли просто написать метод в своем проекте, преобразовать данные и просто перейти в нужный тип. – jmcilhinney

ответ

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

ОК, тогда я верну изменения. Удачи найти ответ. – SSS

+0

'Открытый общий расширитель оператора CType (p As ProjectType) Поскольку SharedType' выглядел многообещающим, но я не мог заставить его работать в IEnumerable – SSS

0

EDIT: Это теперь сообщества вики ответ

В соответствии с просьбой, вот моя попытка реализации 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 в списке. Я думаю, вам придется использовать функции конвертера – SSS

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