为什么在调试和捕获派生异常时看到(empty)属性?

本文关键字:empty 属性 异常 调试 派生 为什么 | 更新日期: 2023-09-27 18:07:07

在阅读和这个问题和答案在这里Stackoverflow我想知道,为什么你可以看到List<string>,但无法访问它。

在我的理解中,不能在基类中访问派生类的成员。那么,为什么偏偏是这样呢?显然你可以看到它,但你不能用它做什么。

为什么在调试和捕获派生异常时看到(empty)属性?

调试器有关于存储在变量中的实际运行时类型的信息-这是。net中运行时元数据的一部分。

这意味着它实际上可以向您显示确切地您正在查看的内容,而编译器只能处理编译时间类型-换句话说,就是您显式(例如Exception)或隐式(var)指定的时间类型。

你可以通过使用反射api复制相同的行为。例如,如果您知道您正在尝试读取的类型包含一个名为Name的属性,该属性的类型为string,但您不知道将要传递的实际类型,您可以使用这样的内容:

public static string GetName(object someObject)
{
  return (string)someObject.GetType().GetProperty("Name").GetValue(someObject);
}

当然,现在我们有了c# 4,我们也可以使用dynamic来实现同样的事情更容易和更快(虽然不安全-它仍然是运行时绑定):

public static string GetName(dynamic someObject)
{
  return someObject.Name;
}

显然,dynamic没有智能感知:)另外值得注意的是,反射允许您读取和操作对象的所有内部状态,而dynamic仍然遵循通常的可访问性修饰符。

你显然不能这么做

catch (Exception ex)
{
    var adresses = ex.lpAdresses;
}

因为ex的编译时类型是Exception,而不是CustomException

调试器OTOH可以检查ex引用的对象的运行时类型并显示其属性。类似于:

catch (Exception ex)
{
    var cex = ex as CustomException;
    if (cex != null)
    {
        var adresses = cex.lpAdresses;
    }
}