문제

인스턴스가 참조로 전달되는 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

참고 값 매개 변수는 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 예어. 이것에 대한 해결 방법이 있습니까?

도움이 되었습니까?

해결책

아니요. C#에서 할 수 없습니다 'out'또는 수정자를 지정하십시오 ref) 이것 말고도 this 확장 방법의 첫 번째 매개 변수의 경우 다른 사람을 위해 할 수 있습니다. VB 구문에 익숙하지는 않지만 확장 방법을 표시하기 위해 선언적 접근 방식을 사용하는 것 같습니다.

당신이 그것을 부를 때, 당신 하지 마라 첫 번째를 지정합니다 this 매개 변수. 따라서 매개 변수를 Out 또는 Ref로 표시하면 정상적인 방법으로 수행 할 때처럼 수정자를 지정할 수 없으므로 의미가 없습니다.

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

여기에있는 문제는 가치 유형이 불변과 관련이 있다고 생각합니다. 평일이 참조 유형이라면 괜찮을 것입니다. 불변의 유형 (structs)의 경우 Defacto 방식은 필요한 값을 가진 새 인스턴스를 반환하는 것입니다. 예를 들어, struct dateTime에서 ADD 메소드가 표시되면 값 = 수신기 DateTime 인스턴스의 값 + param value가있는 새 DateTime 인스턴스를 반환합니다.

public DateTime Add( TimeSpan value )

다른 팁

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#은 ...

그러나 기술적 관점에서 의미가있을 수 있지만 (확장 방법은 정적 메소드이기 때문에) 확장 방법이 인스턴스 방법 인 것처럼 사용되기 때문에 옳지 않다고 생각합니다. 't 수정 this 참조.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top