【问题标题】:Getting rid of objects after using reflection使用反射后摆脱对象
【发布时间】:2016-05-02 09:35:17
【问题描述】:

我一直在尝试使用字符串调用方法,但副作用是每次按下按钮时都会创建一个新对象。我怎样才能摆脱这个?我试过使用 null,但没有运气。

第一次尝试:

string methodName = cboOriginal.Text + "To" + cboConverted.Text;
Type numeralType = typeof(NumeralSystemConversion);
ConstructorInfo numeralConstructor = numeralType.GetConstructor(Type.EmptyTypes);
object numeralObject = numeralConstructor.Invoke(new object[] { });

MethodInfo numeralMethod = numeralType.GetMethod(methodName);
object numeralValue = numeralMethod.Invoke(numeralObject, new object[] { txtOriginal.Text });

txtConverted.Text = numeralValue.ToString();

numeralType = null; numeralConstructor = null; numeralObject = null;
numeralMethod = null; numeralValue = null;

第二次尝试:

string methodName = cboOriginal.Text + "To" + cboConverted.Text;
convert = typeof(NumeralSystemConversion).GetMethod(methodName).Invoke(typeof(NumeralSystemConversion).GetConstructor(Type.EmptyTypes).Invoke(new object[] { }), new object[] { txtOriginal.Text });
txtConverted.Text = convert.ToString();
convert = null;

“convert”对象在应用启动时创建。而 NumeralSystemConversion 是我创建的一个类,方法所在的位置。

我看到的是,每次按下按钮时,诊断工具(Visual Studio 2015 社区)中的内存使用量都会增加。

【问题讨论】:

  • 将语言添加到标签中。从代码中并不总是很明显。
  • 你实际上是用这段代码创建了几个对象:一对strings,一对object数组,可能还有一个隐含的StringBuilder来进行连接。
  • 是的,我知道,这就是我想清理它的原因。

标签: c# object memory reflection


【解决方案1】:

我看到的最大的“清理”是一次(在启动时)创建两个 object 数组并将它们存储在成员变量中:

object[] param1 = new object[] { };
object[] param2 = new object[] { null };

然后在你的方法中:

param2[0] = txtOriginal.Text;
convert = typeof(NumeralSystemConversion).GetMethod(methodName)
    .Invoke(typeof(NumeralSystemConversion).GetConstructor(Type.EmptyTypes)
    .Invoke(param1), param2);
param2[0] = null;

我认为你不能阻止它创建strings。恐怕这就是做生意的成本。 可能的帮助是使用明确的StringBuilder 作为另一个类成员:

StringBuilder methodNameBuilder = new StringBuilder();

在你的函数中:

methodNameBuilder.Clear();
methodNameBuilder.Append(cboOriginal.Text);
methodNameBuilder.Append("To");
methodNameBuilder.Append(cboConverted.Text);
string methodName = methodNameBuilder.ToString();

最后,您看到的内存增加可能只是垃圾,在这种情况下GC.Collect(); 应该清理它们。但在这种情况下,最好不要管它。

【讨论】:

  • 遗憾的是,没有做太多。我真的不明白我是如何创建这么多字符串的。它不应该直接覆盖吗?
  • 是的,它应该销毁旧的并创建新的,除非有其他东西在保留引用。
  • 我添加了一行来清理param2中的引用。
  • 我尝试用 .ToString() 将它变成一个字符串并绕过整个对象,但情况更糟。
  • 也许如果您将您所看到的内容准确地粘贴到问题中,我(或其他人)可以更好地了解情况?
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
相关资源
最近更新 更多