我可以通过Type变量而不是显式类型来转换类的实例吗?

时间:2009-04-08 05:04:55

标签: c# casting

有没有办法使用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;
    }

3 个答案:

答案 0 :(得分: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;
    }

答案 1 :(得分:0)

我并不完全了解您要做的事情,但您可以使用Convert.ChangeType(yourObject,yourType)将对象转换为特定类型。它返回一个object类型的对象,因此您仍然需要手动转换它。我不知道这是否有帮助。

答案 2 :(得分: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!");
    }

虚方法的想法是变量的类型不确定调用哪个实现,而是对象的运行时类型决定它。

据我所知,您所描述的情况是您尝试自己调度对象的运行时类型的方法实现。几乎是虚拟方法的定义。

如果我没有问题,请澄清。 :)