簡體   English   中英

C# 如何在不反射的情況下訪問不同對象上具有相同名稱的屬性?

[英]C# How to access properties with the same name on different objects, without reflection?

假設我有 n 個對象:

class RedSubscriber {

String msisdn {get; set;}
String imsi {get; set;}
...other unique properties specific for RedSubscriber

}


class BlueSubscriber {

String msisdn {get; set;}
String imei {get; set;}
...other unique properties specific for BlueSubscriber

}

  class YellowSubscriber {
    
    String msisdn {get; set;}
    String iccid {get; set;}
    ...other unique properties specific for YellowSubscriber
    
    }

以此類推,對於 n 個對象。

假設我想獲取任何 object 的“String msisdn”值,無論它是什么顏色。 我目前使用反射來做到這一點:

public void getSubscriberMsisdn(Object subscriber){

 Type myType = subscriber.GetType();
  IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());

            foreach (PropertyInfo propertyInfo in props)
            {
                if (propertyInfo == null)
                {
                    continue;
                }

                var propertyValue = propertyInfo.GetValue(subscriber);

                if (propertyValue == null)
                {
                    continue;
                }

                if(propertyInfo.Name.Equals("msisdn")){

                string msisdnValue = propertyValue.ToString();
                Debug.WriteLine("The msisdn is: " + msisdnValue);
                }
            }    

}

正如您所看到的代碼“有效”,但每次我需要檢索一些值時調用它絕對是浪費。 有沒有一種方法可以在不使用上述反射方法的情況下訪問放置在不同對象中的屬性(始終保持相同的名稱和類型)? 任何提示將不勝感激。

是的。 創建接口:

public interface ISubscriber
{
    public string msisdn {get; set;};
}

更改您的類以實現接口,例如:

public class RedSubscriber : ISubscriber
{
    string msisdn {get; set;}
    string imsi {get; set;}
    ...
}

創建一個接受ISubscribergetSubscriberMsisdn()方法:

public void getSubscriberMsisdn(ISubscriber subscriber)
{
    Debug.WriteLine("The msisdn is: " + subscriber.msisdn);
}

不要將反射用於多態性。 接口是一種直接支持多態性的語言特性,在編譯時支持強類型。

在這種情況下,有兩個標准選項:

  1. 界面
  2. Inheritance

在哪里使用並不總是很清楚,而且通常兩種方法都有效。

我認為 inheritance 可以在這里工作,因為您的模型具有非常強的“IS-A”關系。 它可能看起來像這樣:

abstract record Subscriber
{
    public required string Msisdn { get; init; }
}

record RedSubscriber : Subscriber
{
    public required string Imsi { get; init; }
}

record BlueSubscriber : Subscriber
{
    public required string Imei { get; init; }
}

然后

void F(Subscriber s)
{
    Console.WriteLine(s.Msisdn);
}

筆記:

  1. 我將屬性名稱大寫,這是C#方式。
  2. 我利用 'required'+'init' 屬性來確保它們永遠不會是 null
  3. 我使用記錄而不是類,因為它看起來很合適:具有值(而不是引用)相等性的簡單類。
  4. 您不需要使用記錄 - 只需將上面代碼中的“記錄”替換為“類”即可。

順便提一句。 您可以通過使用具有更簡潔語法的位置記錄來刪除一些樣板代碼:

abstract record Subscriber(string Msisdn);

sealed record RedSubscriber(
    string Msisdn, 
    string Imsi)
    : Subscriber(Msisdn: Msisdn);

sealed record BlueSubscriber(
    string Msisdn, 
    string Imei)
    : Subscriber(Msisdn: Msisdn);

暫無
暫無

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

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