簡體   English   中英

通過父類中的函數訪問子類屬性

[英]Accessing child class properties through function in parent class

我的首席技術官( 首席技術官 )讓我想出了一種方法,他可以在基類中編寫一個單獨的函數,並可以訪問子類的所有屬性。 這是我想出的 -

基類

class Assets
{
    public Assets getPropertyVal(Assets asObj)
    {
        PropertyInfo[] propInfos = asObj.GetType().GetProperties();
        string strAttributeValue = "10";
        foreach (PropertyInfo propInfo in propInfos)
        {
            // Getting the value
            var propValue = propInfo.GetValue(asObj, null);

            // Setting the value
            propInfo.SetValue(asObj, Convert.ChangeType(strAttributeValue, propInfo.PropertyType), null);

        }
        return asObj;
    }
}

兒童班

class House : Assets
{
    public int rooms{get; set;}
}

Program.cs文件

class Program
{
    static void Main(string[] args)
    {
        House hsObj = new House();
        hsObj.rooms = 5;

        Assets asObj = hsObj.getPropertyVal(hsObj);
        // Returns asObj as JSON
    }
}

現在這個工作正常,但我只是想知道在C#中是否有更好的方法來做到這一點。

請注意, 我們不知道子類中將存在哪些屬性,因此必須在運行時確定。

更新說清楚 ,我只是想知道是否有更好的方法來訪問子類屬性,一個不使用反射。 需要注意的重要一點是,我們不知道子類可能具有哪些屬性。

更新#2 :我正在使用具有許多實體的產品。 這些實體具有不同的屬性。 我希望能夠在一個地方訪問和使用所有這些屬性。 這個功能正是如此。 這是我可以訪問所有數據的一個地方。

首先,你的Program.cs實際上並沒有“做”你想要的東西。 聽起來你想要一個程序,這樣你就可以這樣做:

Asset myAsset = new House();
myAsset.Rooms = 5;

但是,為什么你甚至想要這樣做呢? 如果您的資產不是眾議院,則會拋出異常,因此您需要首先檢查:

if (myAsset is House)
    myAsset.Rooms = 5;

那時候,你可能只是把它投到了一所房子里。 聽起來您可能想要使用PropertyBag或Dictionary而不是繼承。

我想你所描述的就是這個。 請注意,選項1並不真正限制哪些屬性可用於哪些類,因此我猜這不會對您的特定情況起作用。

// Option 1, a Property Bag (Note: this replaces the properties on the classes)
class Asset
{
    Dictionary<string, object> myPropertyBag = new Dictionary<string, object>();

    public T GetProperty<T>(string property)
    {
        // This throws if the property doesn't exist
        return (T)myPropertyBag[property];
    }

    public void SetProperty<T>(string property, T value)
    {
        // This adds the property if it doesn't exist
        myPropertyBag[property] = (object)value;
    }
}

// Option 2, use a switch and override this function in derived classes
class Asset
{
    public int SomePropertyOnAsset { get; set; }

    public virtual T GetProperty<T>(string property)
    {
        switch (property)
        {
            case "SomePropertyOnAsset": return this.SomePropertyOnAsset;

            default: throw new ArgumentException("property");
        }
    }

    public virtual void SetProperty<T>(string property, T value)
    {
        switch (property)
        {
            case "SomePropertyOnAsset": this.SomePropertyOnAsset = (int)value;

            default: throw new ArgumentException("property");
        }
    }
}

class House : Asset
{
    public int Rooms { get; set; }

    public virtual T GetProperty<T>(string property)
    {
        switch (property)
        {
            case "Rooms": return this.Rooms;

            default: return base.GetProperty<T>(property);
        }
    }

    public virtual void SetProperty<T>(string property, T value)
    {
        switch (property)
        {
            case "Rooms": this.Rooms = (int)value; 
                break;

            default: base.SetProperty<T>(property, value);
                break;
        }
    }
}

然后,這就是你如何使用它們:

// Option 1
Asset asset = new House();
asset.SetProperty("Rooms", 5);
var rooms = asset.GetProperty<int>("Rooms");

// Option 2
Asset asset = new House();
asset.SetProperty("Rooms", 5);
asset.SetProperty("SomePropertyOnAsset", 10);
asset.SetProperty("SomethingElse", 15); // Throws ArgumentException

第三個選項是使Asset成為DynamicObject。 http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

如果您不能或不想對Asset基類進行重大更改或觸摸每個實體,則可能需要使用反射。

Luke Gravitt可能是對的。 你可能只想把它扔到一所房子里。

House myHouse = asObj as House;
if ( myHouse != null )
{
  // do some fun house stuff
}

Yacht myYacht = asObj as Yacht;
if ( myYacht != null )
{
   // put on monocle
}

暫無
暫無

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

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