[英]Passing a reference to a class that inherits from a class that inherits from an interface
[英]Cast a struct to a class inherits from the same Interface
与同事的挑战,关于是否有任何方法可以在此处尝试的示例中将结构强制转换为类
namespace ConsoleApplication22
{
class Program
{
static void Main(string[] args)
{
IFoo fooS = new FooStruct();
fooS.Val = 5;
FooClass foo =(FooClass) fooS;
}
}
public interface IFoo
{
int Val { get; set; }
}
public struct FooStruct : IFoo
{
public int Val { get; set; }
}
public class FooClass : IFoo
{
//public FooClass(int val)
//{
//}
private int val;
public int Val
{
get { return val; }
set { val = value; }
}
}
}
但是我们得到了一个无效的强制转换异常:D
给定接口是引用类型并且类是引用类型并且该类实现了接口,是否有任何技巧可以提取接口并将其分配给类
您不能通过接口直接在两者之间进行转换,这是不允许的,因为它们彼此之间没有直接关系(即继承)。
编译器可以捕获很多这种类型的东西,甚至不允许强制转换进行编译。 如果编译器无法执行此操作,则运行时将执行该操作。 对于显式强制转换,运行时将在失败的强制转换时抛出异常,对于尝试隐式强制转换(仅引用类型),运行时将返回null且不引发异常。
类型检查实际上检查FooStruct
是否是 FooClass
,它不是。
但是,您可以使用强制转换运算符在它们之间进行转换 ,使其看起来像强制转换
class Program
{
static void Main(string[] args)
{
FooStruct f = new FooStruct();
f.Val = 2;
FooClass f2 = (FooClass)f;
Console.Read();
}
}
class FooClass : IFoo
{
public static explicit operator FooClass(FooStruct f)
{
FooClass foo = new FooClass();
foo.Val = f.Val;
return foo;
}
public int Val { get; set; }
}
struct FooStruct : IFoo
{
public int Val { get; set; }
public static explicit operator FooStruct(FooClass f)
{
FooStruct foo = new FooStruct();
foo.Val = f.Val;
return foo;
}
}
// This interface has little use in this scenario.
interface IFoo
{
int Val { get; set; }
}
不要将转换与转换混淆。 另外,请警惕将接口应用于struct
类型,因为可能发生装箱。
没有。
创建一个使用IFoo
实例的FooClass
复制方法,并在其中执行必要的复制。
我能想到的最骇人听闻的方式(您永远都不会使用!)是使用Marshal
:
public unsafe static TDest UnsafeCast<TDest, TSrc>(object source)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(TSrc))];
fixed (byte* b = buffer)
Marshal.StructureToPtr(source, new IntPtr(b), true);
fixed (byte* b = buffer)
return (TDest) Marshal.PtrToStructure(new IntPtr(b), typeof (TDest));
}
这实际上将保存在FooClass
的数据FooStruct
,这允许将其从引用类型“投射”到值类型。
如果使用FooStruct
类型而不是泛型类型参数,则可以选择跳过第二个元帅,方法是将缓冲区直接从缓冲区转换为FooStruct
类型:
fixed (byte* b = buffer)
{
var s = (FooStruct*) b;
return *s;
}
需要unsafe
编译器选项,并且永远也不会在任何类型的生产环境中完成-这是非常缓慢的,不可预测。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.