繁体   English   中英

扩展方法和本地'this'变量

[英]Extension method and local 'this' variable

据我所知, this在扩展方法中作为ref变量传递。 我可以通过这样做验证这一点

public static void Method<T>(this List<T> list)
{
    list.Add(default(T));
}

List<int> ints = new List<int>(new int[] { 1, 2, 3, 4, 5 });
ints.Method();

我的List<int> ints现在是1, 2, 3, 4, 5, 0

但是,当我这样做

public static void Method<T>(this List<T> list, Func<T, bool> predicate)
{
    list = list.Where(predicate).ToList();
}

List<int> ints = new List<int>(new int[] { 1, 2, 3, 4, 5 });
ints.Method(i => i > 2);

我希望我的List<int> ints3, 4, 5但仍然保持不变。 我错过了一些明显的东西吗

this扩展方法参数按值传递,而不是通过引用传递。 这意味着在进入扩展方法时,您有两个指向相同内存地址的变量:原始intslist参数。 将项添加到扩展方法内的列表时,它会反映在ints ,因为您修改了两个变量引用的对象。 重新分配list ,将在托管堆上创建新列表,并且扩展方法的参数指向此列表。 ints变量仍然指向旧列表。

好吧,当你尝试修改某个类实例的属性时,你甚至不需要ref因为你正在修改实例而不是引用它。

在此示例中,您在修改属性时不需要ref关键字:

    class MyClass
    {            
        public int MyProperty { get; set; }
    }

    static void Method(MyClass instance)
    {
        instance.MyProperty = 10;                     
    }

    static void Main(string[] args)
    {
        MyClass instance = new MyClass();
        Method(instance);

        Console.WriteLine(instance.MyProperty);
    }

产量:10

在这里你需要ref关键字,因为你使用引用而不是实例:

    ...

    static void Method(MyClass instance)
    {
        // instance variable holds reference to same object but it is different variable
        instance = new MyClass() { MyProperty = 10 };
    }

    static void Main(string[] args)
    {
        MyClass instance = new MyClass();
        Method(instance);

        Console.WriteLine(instance.MyProperty);
    }

输出:0

对于您的场景,它是相同的,扩展方法与普通静态方法相同,如果您在方法内创建新对象,则要么使用ref关键字(虽然扩展方法不可能)或者返回此对象,否则对它的引用将丢失。

所以在你的第二种情况下你应该使用:

public static List<T> Method<T>(this List<T> list, Func<T, bool> predicate)
{
    return list.Where(predicate).ToList();
}

List<int> ints = new List<int>(new int[] { 1, 2, 3, 4, 5 });
ints = ints.Method(i => i > 2);

foreach(int item in ints) Console.Write(item + " ");

输出: 3, 4, 5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM