【问题标题】:C#: Memory allocation for Anonymous VariablesC#:匿名变量的内存分配
【发布时间】:2010-09-22 06:16:22
【问题描述】:

我对匿名类型变量的内存分配有疑问。

如果我声明一个变量int Vaiable_Name,它将分配4 bytes

但是在Anonymous types 的情况下,会发生什么,以及何时释放内存?

需要我们手动解除分配吗?

例如

List<String> MyList=new List<String>{"0","1","0"}.Where(X=>X!="1").ToList();

这里会为X分配多少bytes

【问题讨论】:

    标签: c# anonymous-types


    【解决方案1】:

    您实际上并没有显示任何匿名类型。您已经展示了一个 lambda 表达式。在这种情况下,编译器将有效地为您创建一个额外的方法,如下所示:

    private static bool SomeUnspeakableName(string X)
    {
        return X != "1";
    }
    

    然后你的代码将被有效地翻译成这个:

    List<String> MyList=new List<String>{"0","1","0"}
           .Where(new Func<string, bool>(SomeUnspeakableName))
           .ToList();
    

    ...除了实际上,在这种情况下编译器会创建一个单独的委托实例,并缓存它。 (当然,它会将扩展方法的使用转化为对Enumerable.WhereEnumerable.ToList 的正常调用。)

    所以X 有效地作为字符串参数结束。在执行时,不存在 lambda 表达式(将表达式树放在一边)。只是使用生成的方法创建了一个委托。

    现在如果你使用匿名类型,像这样:

    var anon = new { Name = "Jon", Age = 34 };
    

    那么这只会创建一个新类,其中包含一个string 变量和一个int 变量,并且与包含string 的普通类具有相同的内存占用(当然这是一个引用)和一个int

    【讨论】:

    • @Jon Skeet:我在问那个 LAMBDA 表达式中的 X
    • @Pramodh:我已经展示了它会发生什么。它有效地成为生成方法中的参数。
    • @Jon Skeet:谢谢...如果我使用for 循环和if 条件而不是上面的 lambda 表达式,这将使用更多内存 lanbda 或for - if 循环?跨度>
    • @Pramodh:鉴于幕后实际发生的事情的复杂性,很难说确切在 JITting 之后会发生什么。但差异将是无关紧要的。您在这里担心的是错误的事情 - 使代码尽可能可读。
    • @ Jon Skeet:谢谢... :-)
    【解决方案2】:
    List<String> MyList = new List<String>{"0","1","0"}.Where(X=>X!="1").ToList();
    

    这不是匿名类型。它是一个集合初始化器,它创建一个包含 3 个元素的列表,然后过滤最初创建的列表。

    匿名类型的行为和消耗与其等效的非匿名类型相同的内存。

    var foo = new 
    {
        Prop1 = "value1",
        Prop2 = "value2"
    };
    

    就像我们有一个类型一样:

    class Foo 
    {
        public string Prop1 { get; set; }
        public string Prop2 { get; set; }
    }
    
    ...
    var foo = new Foo 
    {
        Prop1 = "value1",
        Prop2 = "value2"
    };
    

    【讨论】:

    • @Darin Dimitrov:X 呢?
    • @Pramodh x 不是一个变量,它是一个委托。
    • @RPM1984:不,X是lambda表达式中的参数,最终成为生成方法中的参数。
    • 你说得对,我指的是 lambda (X =>) 的第一部分。我的印象是,lamba 说“X”是一个代表,X!=“1”正在处理它。
    • @RPM1984:不,它是说 X 是委托中的一个参数。整个 lambda 表达式被转换为委托。有关编译器执行的转换,请参阅我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 2018-05-11
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多