Let's say I have n objects:
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
}
And so on, for n objects.
Let's say I want to get the "String msisdn" value of any object, regardless of what color it is. I currently do it using Reflection:
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);
}
}
}
As you can see the code "works", but is absolutely wasteful to call it everytime I need to retrieve some values. Is there a way to access a property (that always maintains the same name and type) that is placed inside different objects, without using the aforementioned reflection method? Any tip will be appreciated.
Yes. Create an interface:
public interface ISubscriber
{
public string msisdn {get; set;};
}
Change your classes to implement the interface, eg:
public class RedSubscriber : ISubscriber
{
string msisdn {get; set;}
string imsi {get; set;}
...
}
Create a getSubscriberMsisdn()
method that takes an ISubscriber
:
public void getSubscriberMsisdn(ISubscriber subscriber)
{
Debug.WriteLine("The msisdn is: " + subscriber.msisdn);
}
Don't use reflection for polymorphism. Interfaces is a language feature that directly supports polymorphism and supports strong typing at compile time.
In situations like this there are two standard options:
Where to use which not always clear and very often both approaches work.
I think inheritance could work here because your models have a very strong "IS-A" relationship. It could look something like this:
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; }
}
And then
void F(Subscriber s)
{
Console.WriteLine(s.Msisdn);
}
Notes:
BTW. You could remove some of the boiler plate code by using positional records with more concise syntax:
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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.