没有C#扩展方法允许通过引用传递参数? [英] Doesn't C# Extension Methods allow passing parameters by reference?

查看:188
本文介绍了没有C#扩展方法允许通过引用传递参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是不是真的不可能创造那里的实例作为参考通过在C#的扩展方法?

Is it really impossible to create an extension method in C# where the instance is passed as a reference?

下面是一个示例VB.NET控制台应用程序:

Here’s a sample VB.NET console app:

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。

Note the Value parameter is passed ByRef.

和(几乎)在C#一样的:

And (almost) the same in 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;
    }
  }
}

添加扩展方法不会在C#中工作,因为我不能使用 REF 关键字。有没有解决方法呢?

The Add extension method doesn’t work in C# because I can’t use the ref keyword. Is there any workaround for this?

推荐答案

没有。在C#中,您不能指定任何修饰符(如出或 REF ),比之外,本的扩展方法的第一个参数 - 你可以为别人。的不熟悉VB语法,但它似乎是用声明的方式来标记的扩展方法。

No. In C#, you cannot specify any modifiers (like 'out' or ref) other than this for the first parameter of an extension method - you can for the others. Not familiar with the VB Syntax but it seems to be using a declarative approach to mark an extension method.

当你调用它,您指定第一个这个参数。因此,标志着参数作为传出或引用没有道理,你不能指定修饰符当你调用它就像你正常的方法做。

When you call it, you do not specify the first this parameter. Hence marking the parameter as out or ref doesnt make sense as You can't specify the modifier when you call it like you'd do for normal methods

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

我觉得你有这里的麻烦是与值类型是不可改变的。如果平日是引用类型,它会制定出好的。对于不可改变的类型(结构),成为事实上的方法是用所需的值返回一个新的实例。例如。查看该结构的DateTime Add方法,它返回的值一个新的DateTime实例=接收器日期时间实例的值+参数值。

I think the trouble you're having here is related to value types being immutable. If Weekdays was a reference type, it would work out alright. For immutable types (structs), the defacto way is to return a new instance with the required value. E.g. See the Add method on the struct DateTime, it returns a new DateTime instance whose value = receiver DateTime instance's value + param value.

public DateTime Add( TimeSpan value )

这篇关于没有C#扩展方法允许通过引用传递参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆