lum*_*ck4 6 c# extension-methods casting
当我试图通过扩展方法强制转换对象时,我遇到了一个奇怪的问题.我有一个类,我在其中包含一些功能IPAddress.
// 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;
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢所有括号的外观来提取IPAddress出对象:
var family = ((IPAddress)prefixLengthAddress).AddressFamily;
Run Code Online (Sandbox Code Playgroud)
我宁愿做这样的事情:
var family = prefixLengthAddress.CastAs<IPAddress>().AddressFamily;
Run Code Online (Sandbox Code Playgroud)
为了做到这一点,我写了以下扩展方法:
public static T CastAs<T>(this object value) where T : class
{
return (T)value;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我得到了一个InvalidCastException:
var family = ((IPAddress)prefixLengthAddress).AddressFamily; // Works
var family = prefixLengthAddress.CastAs<IPAddress>().AddressFamily; // InvalidCastException
Run Code Online (Sandbox Code Playgroud)
我理解在这种特殊情况下我可以简单地IPAddress用getter 公开它,但我们也有更复杂的显式转换,我想这样做.
编辑
感谢Chris Sinclair对使用的评论dynamic我更新了扩展方法,如下所示:
public static T CastAs<T>(this object value)
{
return (T)((dynamic)value);
}
Run Code Online (Sandbox Code Playgroud)
使用有一些开销dynamic,但它足以满足我的需求.它似乎也适用于我尝试过的所有基本类型的铸件.
在第一个示例中,您正在访问用户定义的转换.这仅在演员操作员知道输入类型时才可用PrefixLengthAddress.在通用代码中,编译器只知道类型object和T.它无法访问PrefixLengthAddress此方案中定义的转换.
在这种情况下,您正在做的事情更接近于映射与投射,因为它实际上创建了一个新值.就LINQ而言,你会想要使用Selectvs Cast..
| 归档时间: |
|
| 查看次数: |
1094 次 |
| 最近记录: |