strategy pattern observer net dofactory asp vb.net design-patterns iterator yield

vb.net - observer - state pattern vb net



Patrón iterador en VB.NET(C#usaría rendimiento!) (7)

Esta pregunta ya tiene una respuesta aquí:

¿Cómo implementar el patrón de iterador en VB.NET , que no tiene la palabra clave yield ?


A continuación se muestra la salida: 2, 4, 8, 16, 32

En VB.NET

Public Shared Function setofNumbers() As Integer() Dim counter As Integer = 0 Dim results As New List(Of Integer) Dim result As Integer = 1 While counter < 5 result = result * 2 results.Add(result) counter += 1 End While Return results.ToArray() End Function Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load For Each i As Integer In setofNumbers() MessageBox.Show(i) Next End Sub

Cª#

private void Form1_Load(object sender, EventArgs e) { foreach (int i in setofNumbers()) { MessageBox.Show(i.ToString()); } } public static IEnumerable<int> setofNumbers() { int counter=0; //List<int> results = new List<int>(); int result=1; while (counter < 5) { result = result * 2; counter += 1; yield return result; } }



Hmm, parece que no estás de suerte :

Estaba luchando con un problema hoy al convertir C # a VB.NET. C # tiene una declaración de "retorno de rendimiento" muy buena que se usa en un bloque de iteradores para proporcionar un valor al objeto del enumerador. VB.NET no tiene la palabra clave "yield". Entonces, hay algunas soluciones (ninguna de las cuales es realmente limpia) para evitar esto. Puede usar una declaración de devolución para devolver el valor si está realizando un bucle y desea dividir un enumerador y devolver un único valor. Sin embargo, si desea devolver la enumeración completa, cree una Lista () del tipo secundario y devuelva la lista. Como usualmente usa esto con un IEnumerable, la Lista () funcionará bien.

Eso fue escrito hace un año, no estoy seguro si alguien ha encontrado algo mejor desde entonces ...

Editar: esto será posible en la versión 11 de VB.NET (la que está después de VS2010), se planea el soporte para iteradores. La especificación está disponible aquí .


La palabra clave de rendimiento C # obliga al compilador a crear una máquina de estado en segundo plano para admitirla. VB.Net no tiene la palabra clave yield. Pero tiene una construcción que le permitiría crear una máquina de estado dentro de una función: miembros de la función estática .

Debería ser posible imitar los efectos de una función de retorno de rendimiento mediante la creación de una clase genérica que implemente IEnumerable y la máquina de estados necesaria y coloque una instancia como miembro estático dentro de su función.

Esto, por supuesto, requeriría implementar la clase fuera de la función. Pero si se hace correctamente, la clase debería ser reutilizable en el caso general. Sin embargo, no he jugado con la idea de proporcionar detalles de implementación.


Tenga en cuenta que la ejecución diferida y las propiedades de evaluación diferida de las expresiones y los métodos de LINQ nos permiten implementar de manera efectiva iteradores personalizados hasta que la declaración de rendimiento esté disponible en .NET 4.5. El rendimiento se usa internamente mediante expresiones y métodos LINQ.

El siguiente código demuestra esto.

Private Sub AddOrRemoveUsersFromRoles(procName As String, applicationId As Integer, userNames As String(), rolenames As String()) Dim sqldb As SqlDatabase = CType(db, SqlDatabase) Dim command As DbCommand = sqldb.GetStoredProcCommand(procName) Dim record As New SqlDataRecord({New SqlMetaData("value", SqlDbType.VarChar,200)}) Dim setRecord As Func(Of String, SqlDataRecord) = Function(value As String) record.SetString(0, value) Return record End Function Dim userNameRecords As IEnumerable(Of SqlDataRecord) = userNames.Select(setRecord) Dim roleNameRecords As IEnumerable(Of SqlDataRecord) = rolenames.Select(setRecord) With sqldb .AddInParameter(command, "userNames", SqlDbType.Structured, userNameRecords) .AddInParameter(command, "roleNames", SqlDbType.Structured, roleNameRecords) .AddInParameter(command, "applicationId", DbType.Int32, applicationId) .AddInParameter(command, "currentUserName", DbType.String, GetUpdatingUserName) .ExecuteNonQuery(command) End With End Sub


Todavía estoy entendiendo este concepto también. El artículo Use Iterators en VB Now se publicó recientemente en Visual Studio Magazine.