2009-04-08 63 views
2

有没有一种方法可以使用Type变量而不是显式提供的类型来转换类的实例?可以通过Type变量而不是显式类型来转换类的实例吗?

例如在我的方法下面的“this”是派生类型的“Node”。我希望方法重复尝试从GetNodeIntrinsicProperty()获取一个值,之后如果它获得一个空值,它应该将其自身作为基本类型进行投射,然后重试。

基本上,我想调用GetNodeIntrinsicProperty()的每个实现,直到我得到一个值。

 public string GetIntrinsicProperty(String propertyKey) 
    { 
     //sets the original type value 
     Type currType = this.GetType(); 

     Node thisNode = this; 
     String propertyValue; 

     while (currType is Node) 
     { 
      //casts thisNode as CurrType 
      thisNode = thisNode as currType; 

      /*The live above gives me the following error 
      * 
      * Error 20 The type or namespace name 'currType' could not be found 
      (are you missing a using directive or an assembly reference?) */ 



      //trys to get the property with the current cast 
      //GetNodeIntrinsicProperty() is defined seperately in each type 
      propertyValue = thisNode.GetNodeIntrinsicProperty(propertyKey); 

      if (propertyValue != null) 
      { 
       return propertyValue; 
      } 

      //sets CurrType to its base type 
      currType = currType.BaseType; 
     } 

     return null; 
    } 
+0

你能解释一下你为什么要这样做吗?有一个简单的方法可以确定你是否可以将某种类型转换为其他类型,所以看起来有点愚蠢,只是试图用暴力来实现。 – 2009-04-08 05:09:11

+0

我很困惑。 GetNodeIntrinsicProperty是一个虚拟方法吗?如果是这样,为什么你需要改变类型? – 2009-04-08 05:24:05

+0

同意安德鲁 - 使它虚拟,并使用多态。 – 2009-04-08 06:01:33

回答

0

好吧,首先回答你的问题。

我假设你有一些像这样的结构:

public class Node 
    { 
     public string GetIntrinsicProperty(String propertyKey) 
     { 
      //sets the original type value 
      Type currType = this.GetType(); 

      Node thisNode = this; 
      String propertyValue; 

      while (currType.IsSubclassOf(typeof(Node))) 
      { 
       MethodInfo mi = currType.GetMethod("GetIntrinsicProperty",BindingFlags.Instance | BindingFlags.Public,null,new Type[] {typeof(string)},null); 
       if (mi.DeclaringType != typeof(Node)) 
       { 
        propertyValue = (string)mi.Invoke(this, new object[] { propertyKey }); 

        if (propertyValue != null) 
        { 
         return propertyValue; 
        } 
       } 
       //sets CurrType to its base type 
       currType = currType.BaseType; 
      } 
      return null; 
     } 
    } 

    public class OtherNode : Node 
    { 
     new public string GetIntrinsicProperty(string propertyKey) 
     { 
      return "OtherNode says Hi!"; 
     } 
    } 

    public class TestNode : Node 
    { 
    } 

GetIntrinsicProperty的实施上面会做你问什么,但我认为它是错误的。

你迫使一个孩子班级完全复制你的签名和开发人员,以了解你想要什么。这是虚拟方法的用途。如果我正确理解你做正确的方式你想要的是这样的:

public class Node 
    { 
     public virtual string GetIntrinsicProperty(String propertyKey) 
     { 
      switch(propertyKey) 
      { 
       case "NodeUnderstoodProp": 
        return "I know! Call on me!"; 
       default: 
        return null; 
      } 
     } 
    } 

    public class OtherNode : Node 
    { 
     public override string GetIntrinsicProperty(string propertyKey) 
     { 
      switch (propertyKey) 
      { 
       case "OtherUnderstoodProp": 
        return "I'm the OtherNode, and I know better, call on me!"; 
       default: 
        return base.GetIntrinsicProperty(propertyKey); 
      } 
     } 
    } 

    public class TestNode : Node 
    { 
    } 


    static void Main(string[] args) 
    { 
     Node node = new OtherNode(); 
     var prop1 = node.GetIntrinsicProperty("NodeUnderstoodProp"); 
     var prop2 = node.GetIntrinsicProperty("OtherUnderstoodProp"); 
     var prop3 = node.GetIntrinsicProperty("PropTooHard!"); 

     node = new TestNode(); 
     prop1 = node.GetIntrinsicProperty("NodeUnderstoodProp"); 
     prop2 = node.GetIntrinsicProperty("OtherUnderstoodProp"); 
     prop3 = node.GetIntrinsicProperty("PropTooHard!"); 
    } 

的虚方法的想法是,你的变量的类型并不确定哪种实现被调用,而是跑对象的时间类型决定了它。

据我所知,你描述的情况是你正在尝试做的事情,你自己派遣到对象的运行时类型的方法的实现。几乎是虚拟方法的定义。

如果我没有得到正确的问题,请澄清。 :)

0

我没有完全理解你想要做什么,但你可以将对象转换为使用Convert.ChangeType(yourObject,yourType)的特定类型。它返回一个object类型的对象,所以你仍然必须手动进行转换。我不知道这是否有帮助。

1

好吧我退后一步,并意识到我真的在做的是试图创建一个方法,将通过传递属性名称返回公共属性的值。而不是手动创建我的类中的属性和巧合具有相同名称的字符串之间的关系,我认为最好自动执行该操作。

所以这就是我现在正在做的,它似乎工作。另外,我不必担心两个类试图定义重复的属性键,因为除非存在明确的抽象/覆盖关系,否则派生类已经不能在其基类中拥有重复的属性名称。

public HashSet<string> GetIntrinsicPropertyKeys() 
    { 
     Type t = this.GetType(); 
     PropertyInfo[] properties = t.GetProperties(); 
     HashSet<string> keys = new HashSet<string>(); 

     foreach (PropertyInfo pNfo in properties) 
     { 
      keys.Add(pNfo.Name); 
     } 

     return keys; 
    } 


    public string GetIntrinsicProperty(string propertyKey) 
    { 
     HashSet<string> allowableKeys = this.GetIntrinsicPropertyKeys(); 
     String returnValue = null; 

     if (allowableKeys.Contains(propertyKey)) 
     { 
      Type t = this.GetType(); 
      PropertyInfo prop = t.GetProperty(propertyKey); 

      returnValue = (string)prop.GetValue(this, null); 
     } 
     return returnValue; 
    } 
相关问题