Ich habe ein seltsames Problem, wenn ich versuche, ein Objekt über eine Erweiterungsmethode zu übertragen. Ich habe eine Klasse, in der ich etwas Funktionalität um eine IPAddress
wickle.Explizite Umwandlung in eine Erweiterungsmethode verwenden
// Dumbed down version of class
public sealed class PrefixLengthIPAddress
{
public static explicit operator IPAddress(PrefixLengthIPAddress address)
{
return (address != null) ? address._address : null;
}
public PrefixLengthIPAddress(IPAddress address)
{
_address = address;
_length = address.GetLength();
}
private readonly ushort _length;
private readonly IPAddress _address;
}
Ich mag es nicht das Aussehen der alle Klammern die IPAddress
aus dem Objekt zu extrahieren:
var family = ((IPAddress)prefixLengthAddress).AddressFamily;
würde ich eher der Lage sein, so etwas zu tun:
var family = prefixLengthAddress.CastAs<IPAddress>().AddressFamily;
Um dies zu tun, schrieb ich die folgende Erweiterungsmethode:
public static T CastAs<T>(this object value) where T : class
{
return (T)value;
}
Leider damit ich bin immer ein InvalidCastException
:
var family = ((IPAddress)prefixLengthAddress).AddressFamily; // Works
var family = prefixLengthAddress.CastAs<IPAddress>().AddressFamily; // InvalidCastException
Ich verstehe, dass ich in diesem speziellen Fall einfach die IPAddress
mit einem Getter aussetzen könnte, aber wir haben auch komplexere explizite Casts, die Ich mag würde zu mach das mit.
EDIT
Dank Kommentar Chris Sinclair auf dynamic
ich mit der Erweiterungsmethode aktualisiert aussehen:
public static T CastAs<T>(this object value)
{
return (T)((dynamic)value);
}
Es gibt einige Overhead ist dynamic
mit der Verwendung, aber es ist mehr als schnell genug für meine Bedürfnisse. Es scheint auch mit allen grundlegenden Casting-Typen zu funktionieren, die ich ausprobiert habe.
Nun, 'PrefixLengthIPAddress' hat keine Beziehung in der Typhierarchie zu' IPAddress', die die ultimative Quelle des Problems ist. In welcher anderen Situation würden Sie diesen Casting-Code verwenden? Der Versuch, eine Instanz des Typs A willkürlich auf eine Instanz des Typs B zu erzwingen, ist fehlerhaft. Darüber hinaus ist das Generische tatsächlich unbegrenzt; So könnte 'T' eine' Zeichenfolge' sein, und es kann keine Überladung des Operators auftreten. Ich vermute, dass sogar die Beschränkung auf "IPAddress" für "T" nicht zu dem von Ihnen erwarteten Verhalten führt, und selbst wenn dies der Fall ist, ist Ihre Erweiterung ansonsten nutzlos. – Tejs
Ich mag einfach das Aussehen der Erweiterungsmethode besser. Wenn ich versuchen würde, mein Objekt als String zu erzeugen, würde ich erwarten, dass es eine InvalidCastException wirft. – lumberjack4