valor tipos tipo referencia por pase pasar pasaje parametros parametro objetos funciones como argumentos c# vb.net extension-methods byref

tipos - ¿Los métodos de extensión C#no permiten pasar parámetros por referencia?



pasar tipo como parametro c# (3)

Es extraño que VB.NET lo permita y C # no ...

Sin embargo, aunque podría tener sentido desde un punto de vista técnico (dado que un método de extensión es solo un método estático), creo que no se siente bien, porque los métodos de extensión se usan como si fueran métodos de instancia, y los métodos de instancia pueden no modifique this referencia.

¿Es realmente imposible crear un método de extensión en C # donde la instancia se pasa como referencia?

Aquí hay una aplicación de consola de ejemplo de VB.NET:

Imports System.Runtime.CompilerServices Module Module1 Sub Main() Dim workDays As Weekdays workDays.Add(Weekdays.Monday) workDays.Add(Weekdays.Tuesday) Console.WriteLine("Tuesday is a workday: {0}", _ CBool(workDays And Weekdays.Tuesday)) Console.ReadKey() End Sub End Module <Flags()> _ Public Enum Weekdays Monday = 1 Tuesday = 2 Wednesday = 4 Thursday = 8 Friday = 16 Saturday = 32 Sunday = 64 End Enum Module Ext <Extension()> _ Public Sub Add(ByRef Value As Weekdays, ByVal Arg1 As Weekdays) Value = Value + Arg1 End Sub End Module

Tenga en cuenta que el parámetro Value se pasa por RefRef.

Y (casi) lo mismo en C #:

using System; namespace CS.Temp { class Program { public static void Main() { Weekdays workDays = 0; workDays.Add(Weekdays.Monday); // This won''t work workDays.Add(Weekdays.Tuesday); // You have to use this syntax instead... // workDays = workDays | Weekdays.Monday; // workDays = workDays | Weekdays.Tuesday; Console.WriteLine("Tuesday is a workday: {0}", _ System.Convert.ToBoolean(workDays & Weekdays.Tuesday)); Console.ReadKey(); } } [Flags()] public enum Weekdays : int { Monday = 1, Tuesday = 2, Wednesday = 4, Thursday = 8, Friday = 16, Saturday = 32, Sunday = 64 } public static class Ext { // Value cannot be passed by reference? public static void Add(this Weekdays Value, Weekdays Arg1) { Value = Value | Arg1; } } }

El método Add extensión no funciona en C # porque no puedo usar la palabra clave ref . ¿Hay alguna solución para esto?


No. En C #, no puede especificar ningún modificador (como ''out'' o ref ) que no sea para el primer parámetro de un método de extensión; puede hacerlo para los demás. No está familiarizado con la sintaxis de VB, pero parece estar usando un enfoque declarativo para marcar un método de extensión.

Cuando lo llamas, no especificas el primero this parámetro. Por lo tanto, marcar el parámetro como out o ref no tiene sentido ya que no se puede especificar el modificador cuando se lo llame como lo haría con los métodos normales

void MyInstanceMethod(ref SomeClass c, int data) { ... } // definition obj.MyInstanceMethod(ref someClassObj, 10); // call void MyExtensionMethod(this SomeClass c, int data) {.... } // defn c.MyExtensionMethod(10); // call

Creo que el problema que tienes aquí está relacionado con los tipos de valores que son inmutables. Si Weekdays fue un tipo de referencia, funcionaría bien. Para tipos inmutables (estructuras), la forma defacto es devolver una nueva instancia con el valor requerido. Por ejemplo, vea el método Add en la estructura DateTime, devuelve una nueva instancia de DateTime cuyo valor = valor de param + valor de la instancia de DateTime del receptor.

public DateTime Add( TimeSpan value )


Yikes: estás haciendo una estructura mutable e inmutable. Rompe lo que la gente espera ver en C #, pero si debe, entonces siempre puede llamar directamente al método:

Ext.Add(ref value, arg1);

Cualquier método de extensión es directamente invocable.

Además, una aclaración:

SomeReferenceType value = ...; SomeReferenceType copy = value; value.ExtensionMethodByRef(...); // this failing is semantically ridiculous for reference types, which // is why it makes no sense to pass a `this` parameter by ref. object.ReferenceEquals(value, copy);