装箱和取消装箱带有到接口的强制转换的泛型

本文关键字:转换 泛型 接口 取消装箱 | 更新日期: 2023-09-27 18:01:15

我有下面这样的代码

public interface IFoo
{
    int One { get; set; }
    string Two { get; set; }
}
public class Foo : IFoo
{
    public int One { get; set; }
    public string Two { get; set; }
}
public class SomeDto<T>
    where T : IFoo
{
    public T Fik { get; set; }
    public string Faj { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        var fik = new SomeDto<Foo>() { Fik = new Foo() { One = 1, Two = "ss" }, Faj = "ss" };
        var obj = (Object)fik;
        // the problematic part 
        //=======================
        var fikl = fik as SomeDto<IFoo>;  //do something like that 
                                          //or
        var fikl = (SomeDto<IFoo>)fik;   //do something like that 
    }
}

我该如何处理那个有问题的部分。制作一些类似于允许取消装箱泛型类的东西,但要制作一些更通用的东西,比如接口。

我需要这个,因为我有一个基于泛型的数据源组合框。我需要在列表中找到一些属性形成泛型值的项。

装箱和取消装箱带有到接口的强制转换的泛型

1(没有装箱

2( 不能这样做,因为SomeDto<IFoo>SomeDto<Foo>彼此是不变的。这意味着即使"IFoo可从Foo分配",也不能说"SomeDto<IFoo>可从SomeDto<Foo>分配",反之亦然。

与您的意图类似的是使用协变/逆变通用接口(因为只有委托和接口支持这种技巧(例如

    interface IFoo
    {
        int Int { get; set; } 
    }
    class Foo : IFoo
    {
        public int Int { get; set; }
    }
    interface IDto<out T> where T : IFoo
    {
        T Obj { get; }
    }
    class Dto<T> : IDto<T> where T : IFoo
    {
        public T Obj { get; set; }
    }

因此您可以将IDto<Foo>分配给IDto<IFoo>,如下所示:

    static void Main(string[] args)
    {
        Foo foo = new Foo();
        IDto<IFoo> dto = new Dto<IFoo>() {Obj = foo};
        object obj = dto;
        dto = (IDto<Foo>) obj;
    }