C # - Bestimmen Sie Objekttyp zur Laufzeit
Frage
Hier ist, was ich tun möchte:
public [type determined at runtime] ImageToShow
{
get
{
if(this.IsWebContext)
{
return this.GetString();
}
else
{
return this.GetBitmap();
}
}
}
Auf den ersten Blick scheint es, einfach und machbar, wenn T die generische Typ war, der mit Instanz dieser Klasse erstellt wurde. Aber was ich tun möchte, ist einen String oder Bitmap dient in der Eigenschaft Bild gemacht basierend auf der Bestimmung, so dass das Wissen von dem, was auf dem Server als Bild im Bild ist Eigentum enthalten ist und kein anderer Ort darüber wissen muss. Ich kann auf jeden Fall den Rückgabetyp ‚Objekt‘ machen und es wird funktionieren, aber ich will nicht, Boxen und Unboxing Ineffizienz ich auch nicht Reflexion beteiligt werden soll.
Ich wollte nur mit euch prüfen, ob dies möglich ist, bevor ich auf dieser Idee aufgeben.
Lösung
Boxen tritt auf, wenn Sie einen Wert Typ in einen Referenztyp umwandeln.
int i = 5;
object o = i; // Boxing
Da Sie nur String
oder ein Bitmap
Rückkehr, die beiden Referenztypen sind, können Sie Objekt, ohne sich um Boxen oder Unboxing kümmern können.
Andere Tipps
Wäre es nicht für den Anrufer besser zu „wissen“, eine öffentliche Eigenschaft mit
YourClass.IsWebContext
, was zu erwarten?
Dann würden Sie in der Lage sein, die generischen Typ T zu verwenden.
Scheint, wie stattdessen um diese Arbeits sollten Sie ein anderes Design betrachten. Zum Beispiel eine separate Klasse alle zusammen für alles schaffen, die WebContext und die Durchführung einer gemeinsamen Schnittstelle sein wird.
Zu allererst Referenztypen als Objekt der Rückkehr ist Boxen nicht. Boxen erfolgt nur, wenn ein Valuetype als Reference verwenden.
Lassen Sie uns jetzt sagen, Sie das Objekt Rückgabetyp verwenden. Dann können Sie überprüfen, ob die Objektinstanz, die zurückgegeben wird eines bestimmten Typs ist mit dem is
Operator.
object o = myClass.ImageToShow;
if (o is String)
{
// Use as a String
}
else if (o is Bitmap)
{
// Use as a Bitmap
}
Zweitens würde ich nicht empfehlen IsWebContext
in jeder Eigenschaft überprüfen. Es würde mehr Sinn machen, eine Basisklasse zu schaffen und die Umwelt gegeben spezialisiert sie in verwendet wird.
Ja, verwenden Sie eine Schnittstelle.
public interface IAmImage {}
public class StringImage: IAmImage
{
private string img;
public string Image { get { return img; } set { img = value; } }
public StringImage(string image) { img = image;}
}
public class BitmapImage: IAmImage
{
private Bitmap img;
public Bitmap Image { get { return img; } set { img = value; } }
public BitmapImage(Bitmap image) { img = image;}
}
... und in der Client-Code ....
public IAmImage ImageToShow
{
get
{
return this.IsWebContext?
new StringImage(this.GetString()):
new BitmapImage(this.GetBitmap());
}
}