【问题标题】:Calling Known Property from Unknown Class从未知类调用已知属性
【发布时间】:2013-06-14 10:35:31
【问题描述】:

我有一个 BaseClass,我使用继承从中派生了多个其他类。 在其他地方,我希望能够从这些继承类中的任何一个中检索属性,即使类的类型直到运行时才知道。

例如,假设我有两个从 BaseClass 派生的类

FirstClass : BaseClass
SecondClass : BaseClass

我的 BaseClass 有一个名为 ID 的属性,它是一个 int(以及许多其他属性)

在运行时,我的应用将接收到“FirstClass”对象或 SecondClass 对象,但无论哪种方式,我都需要检索 ID 属性。

public int MyMethod(object unknownClass)
{
    int myID = unknownClass.ID; 
    return myID                    //...does not compile
}

public int MyMethod(object unknownClass)
{
    BaseClass tryCasting = (BaseClass)unknownClass;
    int myID = tryCasting.ID;           
    return myID                    //...does not compile either
}

我不确定还可以尝试什么。 如何在不首先知道对象类型的情况下获得我知道存在的属性?

【问题讨论】:

  • 第二种方法有什么错误?缺少一个分号,但我想这不是你在说的。
  • @TimRogers 如果你仔细观察,他总是在返回时错过分号
  • @PJW:你听说过继承吗?

标签: c# .net


【解决方案1】:

不要使用对象,使用BaseClass:

public int MyMethod(BaseClass unknownClass)
{
    int myID = unknownClass.ID; 
    return myID;                    
}

【讨论】:

    【解决方案2】:

    请参阅 Darren Davies 的回答,了解您的具体 ID 案例。当属性是在派生类而不是基类中定义时,此答案中的方法很有用。


    使用dynamic 代替object。这将使用运行时来检索实际的对象类型。

    public int MyMethod(dynamic unknownClass)
    {
        int myID = (int)unknownClass.ID; 
        return myID;
    }
    

    或者,您可以使用反射来检索属性值:

    var myID = (int)unknownClass.GetType().GetProperty("ID").GetValue(unknownClass);
    

    【讨论】:

    • dynamic 如果您可以轻松避免它,这不是一个好方法。除了速度慢之外,它还有可能将编译错误转化为运行时错误。
    • dynamic 和反射似乎有点矫枉过正。
    • 同样的反思意见。这是对这些功能的滥用。
    • 在 OP 的情况下 - 这 矫枉过正,但这也是我看到标题后的第一个想法,而且这个词 unknown 很多次。如果该类确实未知,那么这是最好的答案。
    • 几乎不需要反射,除非你正在构建一个序列化库或类似的东西。不存在未知类,那叫“我不知道接口是什么”。
    【解决方案3】:

    多态是答案。您应该知道,当您创建从另一个派生的类时,派生类会立即从基类获取属性。因此,如果您不重新定义方法(覆盖),当您在派生类上调用方法 MyMethod 时,它将 总是调用基本方法。所以下一个代码应该可以正常工作:

    BaseClass { 
        private : int id ; 
        public  : int getId { return id ; }
    } ;
    
    FirstClass : BaseClass { DO NOT OVERRIDE getID ...} ; 
    
    int main (void) { 
        BaseClass base ; 
        FirstClass first ; 
        base = first ; 
        base.getId() ; //Gets the id of first.
    }
    

    这个程序是做什么的?当您将first 分配给base 时,您将first 类型转换为BaseClass。然后,当您执行base.getId() 时,程序查找如果 FirstClass 中有此方法的重新定义(覆盖),如果没有,则调用基方法。

    希望这些信息对您有用。您应该阅读 Bruce Eckels 的“Thinking in C++”的第一章,这是对面向对象编程的一个很好的介绍。

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 2018-09-07
      • 1970-01-01
      • 2023-01-04
      • 1970-01-01
      • 2019-05-07
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多