簡體   English   中英

我可以通過Type變量而不是顯式類型來轉換類的實例嗎?

[英]Can I cast an instance of a class by a Type variable rather then an explicit type?

有沒有一種方法可以使用Type變量而不是顯式提供的類型來強制轉換類的實例?

例如,在我下面的方法中,“ this”是“ Node”的派生類型。 我希望該方法反復嘗試從GetNodeIntrinsicProperty()獲取一個值,此后如果它為null值,則應將其自身強制轉換為基本類型,然后重試。

基本上,我想調用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;
    }

好吧,我退后了一步,意識到我真正在做的是嘗試創建一種方法,該方法將通過傳遞屬性名稱來返回公共屬性的值。 與其在我的類中的屬性和一個恰好具有我所認為的相同名稱的字符串之間手動創建關系,不如自動地這樣做更好。

所以這是我現在正在做的事情,它似乎起作用了。 另外,我不必擔心兩個類試圖定義重復的屬性鍵,因為派生類在其基類中已經不能具有重復的屬性名,除非存在顯式的抽象/覆蓋關系。

    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;
    }

我不完全了解您要做什么,但是您可以使用Convert.ChangeType(yourObject,yourType)將對象轉換為特定類型。 它返回對象類型為object的對象,因此您仍然必須手動對其進行強制轉換。 我不知道這有沒有幫助。

好的,那么首先回答您的問題。

我假設您具有這樣的結構:

    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!");
    }

虛擬方法的思想是變量的類型不決定調用哪個實現,而是由對象的運行時類型決定。

據我所知,您所描述的情況是您嘗試針對對象的運行時類型自行調度方法的實現。 幾乎是虛擬方法的定義。

如果我沒有正確回答問題,請澄清。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM