Разве методы расширения C# не позволяют передавать параметры по ссылке?
действительно ли невозможно создать метод расширения в C# , где экземпляр передается в качестве ссылки?
вот пример 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
Примечание параметр Value передается ByRef.
и (почти) то же самое в 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;
}
}
}
на Add
метод расширения не работает в C#, потому что я не могу использовать ref
ключевое слово. Есть ли обходной путь для этого?
3 ответов
нет. В C#не может укажите любые модификаторы (например, " out " или ref
), кроме this
для первого параметра метода расширения - вы можете для других. не знаком с синтаксисом VB, но, похоже, использует декларативный подход для обозначения метода расширения.
когда вы называете его, вы не Укажите первый
Yikes-вы делаете изменяемую неизменяемую структуру. Он разрушает то, что люди ожидают увидеть в C#, но если вы должны, то вы всегда можете напрямую вызвать метод:
Ext.Add(ref value, arg1);
любой метод расширения непосредственно востребуемых.
кроме того, уточнение:
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);
странно, что VB.NET позволяет это, а C# - нет...
однако, хотя это может иметь смысл с технической точки зрения (поскольку метод расширения-это просто статический метод), я думаю, что это неправильно, потому что методы расширения используются так, как если бы они были методами экземпляра, а методы экземпляра не могут изменить this
ссылка.