类创建内存加载/匿名类

时间:2013-05-23 18:59:24

标签: c# anonymous-class

在应用程序中工作,并为“例外”列出了以下扩展方法:

public static void FillData(this Exception target, object data)
{
   if (target == null)
      throw new ArgumentNullException("target");
   if (data == null)
      throw new ArgumentNullException("data");

   string stackTraceSite = target.LastStackTraceSite();
   var stringDict = new System.Collections.Specialized.StringDictionary();

   PropertyInfo[] pis = data.GetType().GetProperties();
   int pisLen = pis.Length;

   for (int i = 0; i < pisLen; i++)
   {
      string key = (stackTraceSite != null ? stackTraceSite + '.' : null) + pis[i].Name;
      try
      {
         target.Data[key] = pis[i].GetValue(data, null) ?? "null";
      }
      catch (ArgumentException ae)
      {
         target.Data[key] = "ARGUMENT EXCEPTION -> " + ae.Message;
      }
   }
}

然后以类似的方式调用或使用它:

try
{
   // Perform some dangerous operation that throws an exception
}
catch (Exception ex)
{
   ex.FillData(new { CustId = 4, Category = "Foo", Style = "bar" });
   Logger.LogError(ex);
}

匿名类型的成员(如示例中)在某些情况下被“重用”,但在许多其他情况下,它们是完全不同的。 (例如new { FileType = Enum.FileType.RejectionLetter, FilePath = loadFilePath }

这种代码在很多地方使用,并且在一个会吸引大量流量的网络应用程序中。我想知道的一个问题是:所有这些匿名类的定义是否会最终陷入困境/崩溃/即使/当它们没有被捕获时,也会产生很大的内存负载?

1 个答案:

答案 0 :(得分:1)

如果属性名称集相同,则将重用该类型。

class Program
{
    static void Main(string[] args)
    {

        var test = new Test();
        var inner = test.Go();
        var anonObj = new { Name = "one" };
        Console.WriteLine(inner == anonObj.GetType()); // true
    }
}

public class Test
{
    public Type Go()
    {
        var anonObj = new { Name = "one" };
        return anonObj.GetType();
    }
}

因此,您不会遇到具有相同属性集的多个调用的问题。但是这些定义本身呢?我写了一个快速实验,看看会发生什么。

class Program
{
    static void Main(string[] args)
    {

        new Test().Go();
        Console.WriteLine("End: " + GC.GetTotalMemory(true));
        Console.ReadLine();
    }
}

public class Test
{
    public void Go()
    {
        var anonObj = new { Name = "one" };
        Console.WriteLine(GC.GetTotalMemory(true));
    }
}

声明anon类型之后内存使用率更高,即使在所有引用都已消失并且垃圾收集之后,所以我假设类型定义在GC之后确实存在,因此是为了AppDomain的生命周期。所以从理论上讲,这可能是一个问题。

但是,它只会为唯一的属性组合创建类型,因此,除非这是一个非常大型代码库,否则它不会引起任何问题。

Erick