C# 如何修改函数';s的行为基于是否将其分配给变量?

C# 如何修改函数';s的行为基于是否将其分配给变量?,c#,C#,如标题所示 我知道这在其他语言中是可能的——是C语言吗 如果问题标题不清楚,我想做(类似)这样的事情: 这是不是不用魔法就能做到的?如果这是可能的,但以某种恶劣的方式,那是什么方式 编辑:对于那些希望看到一个可以这样做的示例的人(在python中):。请注意,我警告它的问题,它并不总是工作-但这只是关系到我做的方式,当我回答这个问题。现在我了解了更多有关inspect的信息,您可以从堆栈中获得所需的所有信息,以确定它是否被分配到任何位置。这是不可能的。编译器可以进行优化 MyClass exam

如标题所示

我知道这在其他语言中是可能的——是C语言吗

如果问题标题不清楚,我想做(类似)这样的事情:

这是不是不用魔法就能做到的?如果这是可能的,但以某种恶劣的方式,那是什么方式


编辑:对于那些希望看到一个可以这样做的示例的人(在python中):。请注意,我警告它的问题,它并不总是工作-但这只是关系到我做的方式,当我回答这个问题。现在我了解了更多有关inspect的信息,您可以从堆栈中获得所需的所有信息,以确定它是否被分配到任何位置。

这是不可能的。编译器可以进行优化

MyClass exampleObject2=exampleObject1.sort()
to
exampleObject1.sort()如果未使用
exampleObject2


回答一个稍微不同的问题:您可以返回一个
Lazy
。因此,只有在实际使用结果时,才能进行排序。

这是不可能的。编译器可以进行优化

MyClass exampleObject2=exampleObject1.sort()
to
exampleObject1.sort()如果未使用
exampleObject2


回答一个稍微不同的问题:您可以返回一个
Lazy
。因此,只有在实际使用结果时才能进行排序。

将复制和排序方法拆分为两个不同的方法。如果我想对副本进行排序,我应该在排序之前负责复制。例如:

var copy = myCollection.Copy();
copy.Sort();

目标应该是明确你的函数对任何调用代码做了什么。基于使用情况的不同行为只会导致bug,至少在C世界是这样。

将复制和排序方法分为两种不同的方法。如果我想对副本进行排序,我应该在排序之前负责复制。例如:

var copy = myCollection.Copy();
copy.Sort();
目标应该是明确你的函数对任何调用代码做了什么。基于使用情况的不同行为只会导致bug,至少在C#world中是这样。

当然,你绝对不应该这样做,但既然OP更感兴趣的是,如果出于好奇,可以这样做,那么下面是一段代码,演示了这一功能:

class SomeWeirdClass
{
    private bool sortApplied = false;
    private List<int> elements;

    public IList<int> Elements
    {
        get
        {
            if(sortApplied)
            {
                elements.Sort();
                sortApplied = false;
            }

            return elements;
        }
    }

    public SomeWeirdClass(IEnumerable<int> elements)
    {
        this.elements = elements.ToList();
    }

    public SortedWeirdClass Sort()
    {
        sortApplied = true;

        return new SortedWeirdClass(this);
    }

    public class SortedWeirdClass
    {
        SomeWeirdClass parent;

        internal SortedWeirdClass(SomeWeirdClass parent)
        {
            this.parent = parent;
        }

        public static implicit operator SomeWeirdClass(SortedWeirdClass sorted)
        {
            sorted.parent.sortApplied = false;

            var elementCopy = new int[sorted.parent.elements.Count];
            sorted.parent.elements.CopyTo(elementCopy);

            var result = new SomeWeirdClass(elementCopy);
            result.Sort();

            return result;
        }
    }    
}
程序输出:

Original Data:
5 1 4 3 2
Original Data after Sort and Assignment:
5 1 4 3 2
Sorted Copy:
1 2 3 4 5
Original Data after Sort without Assignment:
1 2 3 4 5
这里的黑客行为是排序实际上创建了一个临时类,它包装了原始类。除非该结果通过赋值隐式转换为原始类型,否则排序效果将应用于原始数据集。如果进行赋值,则取消排序,并为新变量创建副本。

当然,您绝对不应该这样做,但由于OP更感兴趣的是,如果出于好奇可以这样做,那么下面是一段代码,演示此功能:

class SomeWeirdClass
{
    private bool sortApplied = false;
    private List<int> elements;

    public IList<int> Elements
    {
        get
        {
            if(sortApplied)
            {
                elements.Sort();
                sortApplied = false;
            }

            return elements;
        }
    }

    public SomeWeirdClass(IEnumerable<int> elements)
    {
        this.elements = elements.ToList();
    }

    public SortedWeirdClass Sort()
    {
        sortApplied = true;

        return new SortedWeirdClass(this);
    }

    public class SortedWeirdClass
    {
        SomeWeirdClass parent;

        internal SortedWeirdClass(SomeWeirdClass parent)
        {
            this.parent = parent;
        }

        public static implicit operator SomeWeirdClass(SortedWeirdClass sorted)
        {
            sorted.parent.sortApplied = false;

            var elementCopy = new int[sorted.parent.elements.Count];
            sorted.parent.elements.CopyTo(elementCopy);

            var result = new SomeWeirdClass(elementCopy);
            result.Sort();

            return result;
        }
    }    
}
程序输出:

Original Data:
5 1 4 3 2
Original Data after Sort and Assignment:
5 1 4 3 2
Sorted Copy:
1 2 3 4 5
Original Data after Sort without Assignment:
1 2 3 4 5

这里的问题是排序实际上创建了一个临时类来包装原始类。除非该结果通过赋值隐式转换为原始类型,否则排序效果将应用于原始数据集。如果进行赋值,则取消排序,并为新变量创建一个副本。

对这种类型的用户来说,这样做将是残酷和不寻常的惩罚,即使您可以这样做,那么您为什么要这样做呢?如果要公开这两个操作,请使用两种不同的方法,一种是
void
,另一种是返回新集合。我知道,根据调用方式的不同,行为会发生变化,这可能会造成混乱和不愉快。这不是重点。这更像是一种好奇。这是我以前在其他库中见过的特性(虽然我不记得在c#中见过),所以我知道有时候这是可能的。我相信python的matplotlib中的交互式绘图就是这样(我知道如何在python中实现),但我不知道如何在c#中实现。@Servy-从您下面的评论中,您清楚地理解了我的问题-您知道一种实现方法吗?
我知道这在其他语言中是可能的-是在c#中吗?
您能举个例子吗,请?@mason如果您计划将原始值用于其他用途,您应该将排序后的值存储在其他位置,以便您仍然可以使用该原始值。专门返回新集合的主要原因是,您仍然拥有原始集合。它还发出非常糟糕的信号。当一个方法返回一个新值时,它意味着它没有改变对象本身。如果我调用一个返回一个新的排序集合的排序方法,我不希望它也会对原始集合进行变异。对这种类型的用户来说,这样做是残酷和不寻常的惩罚,即使你可以这样做,那么你为什么要这样做呢?如果要公开这两个操作,请使用两种不同的方法,一种是
void
,另一种是返回新集合。我知道,根据调用方式的不同,行为会发生变化,这可能会造成混乱和不愉快。这不是重点。这更像是一种好奇。这是我以前在其他库中见过的特性(虽然我不记得在c#中见过),所以我知道有时候这是可能的。我相信python的matplotlib中的交互式绘图就是这样(我知道如何在python中实现),但我不知道如何在c#中实现。@Servy-从您下面的评论中,您清楚地理解了我的问题-您知道一种实现方法吗?
我知道这在其他语言中是可能的-是在c#中吗?
您能举个例子吗,请?@mason如果您计划将原始值用于其他用途,您应该将排序后的值存储在其他位置,以便您仍然可以使用该原始值。专门返回新集合的主要原因是,您仍然拥有原始集合。它还发出非常糟糕的信号。当一个方法返回一个新值时,它意味着它没有改变对象本身。如果我调用一个sort方法返回一个新的排序c