【问题标题】:Dynamic cast at runtime运行时动态转换
【发布时间】:2017-08-21 11:05:23
【问题描述】:

有没有办法像下面的伪代码那样在运行时动态转换:

foreach (DataRow row in table.Rows)
{
    foreach (DataColumn col in table.Columns)
    {
        if (row[col] != DBNull.Value)
        {
            Type type = col.DataType;

            type cellContent = (type)row[col]; //Pseudo-Code
        }
    }
}

我一直在网上搜索,但没有找到任何东西。有object obj = Activator.CreateInstance(type);,但我仍然被一个对象困住,不能对它使用特定的类型方法。我还需要一个现有对象的转换,而不是一个新实例。我需要从 CellContent 中删除所有 EventHandler,因为在某些情况下它们会导致内存泄漏,例如:对象类型是 IList[SerialNumberGridViewModel] 并且 SerialNumberGridViewModel 实现了导致内存泄漏的 PropertyChanged-Handler。任何想法?有没有办法解决这个问题?

我已经在上述特定情况下解决了这个问题,但是一般的方法会好很多,因为我正在使用的程序很大并且有很多内存泄漏需要删除。

【问题讨论】:

  • 不确定你的意思。你能举个例子吗?
  • 不,因为这没有任何意义。您将如何使用cellContent,因为您仍然不知道类型是什么。如果您知道要访问的成员,那么最好的解决方案是创建一个包含这些成员的类型(例如接口或基类),然后强制转换为该类型。如果做不到,请使用dynamic 或反射。
  • 你的伪代码目前什么都不做。目前还不清楚你在问什么。内存泄漏是完全不同的故事,要么删除它,要么问另一个问题。
  • 有些误会。如果您不知道“cellContent”变量的类型,您能否举例说明接下来要对“cellContent”变量做什么?可能是反射是你在找什么?
  • @Sinatr:如果我将 cellContent 转换为它实际存在的对象,我可以删除它的事件。标记为伪代码的行只是为了演示我实际尝试做的事情 - 它确实如此。那为什么还不清楚呢?

标签: c# wpf dynamic types casting


【解决方案1】:

没有。您不能强制转换为编译时未知的任何类型。但是,c# 确实有一个特殊的关键字来声明未知类型的变量 - 它是 dynamic
您可以将其视为late binding 的一种形式 - 变量的实际类型仅在运行时确定。
当你声明一个动态变量时,c#编译器实际上创建了一个object类型的变量,但不进行任何类型检查。

动态类型允许其发生的操作绕过编译时类型检查。相反,这些操作是在运行时解决的。
...
在大多数情况下,动态类型的行为类似于类型对象。但是,包含动态类型表达式的操作不会被编译器解析或类型检查。编译器将有关操作的信息打包在一起,这些信息稍后用于在运行时评估操作。作为该过程的一部分,动态类型的变量被编译为对象类型的变量。因此,动态类型只存在于编译时,而不存在于运行时。

【讨论】:

  • 感谢您的回答。这是我需要的信息。
  • 我成为这里的会员已经 3 年多了。据我所见,大多数好的明确问题都会得到好的、明确的答案。有时这只是你如何写问题的问题。但是,我认为这个问题不值得反对。
【解决方案2】:

好吧,我会试一试。关于反射的部分有点令人困惑,但我认为您正在寻找的是Dispose 模式。

检查:https://msdn.microsoft.com/en-us/library/ms244737.aspx

所有需要清理代码的类,例如SerialNumberGridViewModel 将实现 IDisposable。从外面你会投到IDisposable,然后打电话给Dispose()。每个对象自己决定现在必须做什么,例如删除事件处理程序等。

问候

【讨论】:

    猜你喜欢
    • 2012-09-06
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    相关资源
    最近更新 更多