2016-01-07 6 views
0

Я создаю массивы структур определяется, когда разделся до предметов первой необходимости для целей этого вопроса, как это: -Как суммировать массив структур?

Public Structure MyStruct 

    Public innards As Double 

    Public Shared Operator +(ByVal example1 As MyStruct, ByVal example2 As MyStruct) As MyStruct 
     Dim out_struct As MyStruct 
     out_struct.innards = example1.innards + example2.innards 
     Return out_struct 
    End Operator 

End Structure 

Я затем создать массив: -

Dim my_struct1 As MyStruct 
Dim my_struct2 As MyStruct 
Dim my_struct3 As MyStruct 

my_struct1.innards = 1 
my_struct2.innards = 2 
my_struct3.innards = 3 

Dim my_struct_array() As MyStruct = {my_struct1, my_struct2, my_struct3} 

и я хочу вычислить сумму элементов массива: -

Dim my_total As MyStruct 
my_total = my_struct_array.Sum 

, но это приводит к ошибке компиляции: -

Overload resolution failed because no accessible 'Sum' accepts this number of arguments.

Есть ли способ заставить это работать? Какой интерфейс мне нужно реализовать? Или мне нужно прибегнуть к LINQ?

ответ

1

Массивы не имеют Sum функцию, но вы можете использовать LINQ; однако LINQ не видит ваш оператор +, поскольку он работает только с предопределенными числовыми типами.

Dim my_total As double 
my_total = my_struct_array.Sum(Function(x) x.innards) 

Ваш оператор + работает только если вы работаете с MyStructs явно:

Dim t As MyStruct = my_struct1 + my_struct2 

Вы могли бы определить общую Sum функцию или метод расширения. Вот Sum функция

Public Shared Function Sum(items As IEnumerable(Of MyStruct)) as MyStruct 
    Dim total as double 

    For Each x In items 
     total += x.innards 
    Next 
    dim t as New MyStruct 
    t.innards = total 
    Return t 
End Function 

и назвать его так:

t = MyStruct.Sum(my_struct_array) 

Как метод расширения:

Public Module MyExtensions 
    <Extension()> 
    Public Function Sum(items As IEnumerable(Of MyStruct)) as MyStruct 
     Dim total as double 

     For Each x In items 
      total += x.innards 
     Next 
     dim t as New MyStruct 
     t.innards = total 
     Return t 
    End Function 
End Module 

Тогда вы можете делать то, что вы намеревались первый:

t = my_struct_array.Sum() 

Еще одна вещь: Структуры должны быть неизменными.Причина в том, что вы всегда получаете копию структур, а не ссылок, когда получаете доступ к значениям структур, которые находятся в коллекциях. Если вы это сделаете:

my_struct_list(2).innards = 100 

... вы не получите ожидаемого результата! Индекс списка возвращает копию структуры внутри списка, а затем вы изменяете поле innards этой копии, но структура в списке не будет изменена!

Поэтому создать-структуру, как это:

Public Structure MyStruct 
    Private ReadOnly m_value As Double 

    Public Sub New (value as Double) 
     m_value = value 
    End Sub 

    Public ReadOnly Property Value() As Double 
     Get 
      Return m_value 
     End Get 
    End Property 

    Public Shared Operator +(ByVal x As MyStruct, ByVal y As MyStruct) As MyStruct 
     Return New MyStruct(x.m_value + y.m_value) 
    End Operator 
End Structure 

Эта структура неизменна. Вы не можете изменить значение после его инициализации с помощью New(initialValue). Если вы хотите изменить значение в списке, вам необходимо сделать это:

my_struct_list(2) = New MyStruct(100) 

Это будет вести себя так, как ожидалось.

1

Поскольку это Structure и имеет базовые типы, существует способ сделать это с помощью предиката, который будет указывать на цикл, значение которого имеет значение Sum. my_total - это неправильный тип, если вы пытаетесь получить значение всего innards.

Dim my_total = my_struct_array.Sum(Function(ms) ms.innards) 
+0

Он производит двойной, не MyStruct. –

+0

Мысль, что он был после? – OneFineDay

+0

Dim my_total Как MyStruct. Так нет. –

1

Согласно методу MSDNSum() нужен один аргумент, а также возвращаемое значение имеет тип Double, что означает, что он не может рассчитать структуру. Вам нужно будет вычислить значения внутри него.

Попробуйте что-то вроде этого:

Dim my_total As MyStruct 
my_total.innards = my_struct_array.Sum(Function(ms) ms.innards) 
1

В простой старый :) vb.net вы могли бы попробовать

Dim my_total As MyStruct 
For Each item As MyStruct In my_struct_array 
    my_total.innards = my_total.innards + item.innards 
Next 
1

Составьте список (Of MyStructure) и суммируя его с помощью

ListOfMyStruct.Sum(Function(x) x.innards) 
Смежные вопросы