定义了一个泛型类, 有什么办法能将一个泛型类实例赋值给未指定泛型的泛型类吗? 类似 Java 里的 List = new ArrayList<String>() - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bthulu
V2EX    C#

定义了一个泛型类, 有什么办法能将一个泛型类实例赋值给未指定泛型的泛型类吗? 类似 Java 里的 List = new ArrayList<String>()

  •  
  •   bthulu 2022 年 5 月 20 日 2110 次点击
    这是一个创建于 1364 天前的主题,其中的信息可能已经有所发展或是发生改变。

    C#自身是通过定义两个同名但不同命名空间的类来解决的, 这可能是历史遗留问题导致的.

    System.Collections.IList list = new List<int>(); System.Collections.Generic.IList<int> list = new List<int>(); 

    如果我自己有这么个类 Singer<T>, 有一个实例是反射创建的, 要把这个实例赋值给 Singer, 这要怎么处理呢?

    var instance = Activator.CreateInstance(...); // 下面这句怎么写? 这里确实可以通过反射拿到 instance 的具体类型, 但是代码里如何才能赋值给一个 Singer? // java 里可以用?或者 object 代替, 但是 C#里就直接报错了 Singer<?> singer = instance; 
    12 条回复    2022-08-07 23:57:58 +08:00
    hez2010
        1
    hez2010  
       2022 年 5 月 20 日 via Android
    不是的,C# 里面非泛型的集合类接口和类型是已经淘汰的类型,一般不会使用。
    zgcwkj
        2
    zgcwkj  
       2022 年 5 月 22 日
    不知道我理解对不对,可以试试 CopyTo 或者 Linq 赋值
    INCerry
        3
    INCerry  
       2022 年 5 月 22 日
    如果我理解没错,那你直接强转就可以了呀
    ```C#
    var obj = Activator.CreateInstance(typeof(List<int>));
    List<int> intList = (List<int>)obj;
    Console.WriteLine(intList.Count);
    ``
    bthulu
        4
    bthulu  
    OP
       2022 年 5 月 23 日
    @INCerry 强转你得知道确切的类型啊,我都知道确切的类型了, 我还反射创建实例干嘛,我直接 new 不好么?
    问题就出在这个类型事先是不知道的,是通过 json 配置文件里的注册信息匹配到类的 Type ,你仅仅知道类的 Type , 这个 type 也是通过 Assemble 遍历所有的类,将其中实现了某个接口的类的类型注册到注册器中。就像下面这样, 你怎么个强转法?
    ```
    static Dictionary<string, Type> registers = new();

    Type type = registers["key"];
    var obj = Activator.CreateInstance(type);
    ```
    INCerry
        5
    INCerry  
       2022 年 5 月 23 日
    @bthulu 那你题目里面的例子举的不是很好,简单的方案你可以直接用 dynamic 或者上面你提到的直接用 IList 。复杂的方案代码生成(表达式树、Emit )
    ```
    var obj = Activator.CreateInstance(typeof(List<int>));
    dynamic intList = obj;
    Console.WriteLine(intList.Count);
    intList.Add(1);
    Console.WriteLine(intList[0]);
    // output :
    // 0
    // 1
    ```
    INCerry
        6
    INCerry  
       2022 年 5 月 23 日
    @INCerry 还有 Roslyn 动态编译,类似 natasha 那样
    SMGdcAt4kPPQ
        7
    SMGdcAt4kPPQ  
       2022 年 5 月 23 日 via Android   1
    让 Singer<T>继承 Singer 即可
    forgottencoast
        8
    forgottencoast  
       2022 年 6 月 2 日
    @ComputerIdiot
    一般都是这样处理,也符合 OO 。
    Aloento
        9
    Aloento  
       2022 年 7 月 22 日
    bthulu
        10
    bthulu  
    OP
       2022 年 7 月 23 日
    @Aloento 继承不行的. Singer<T>里可以定义方法 Add(T t), Singer 里可就没法这样定义了.
    Singer<T>继承 Singer, 将 Singer<T>实例赋值给 Singer, 那就没法调用 Add 方法了, 只能转换成 dynamic 去调了
    Aloento
        11
    Aloento  
       2022 年 7 月 24 日
    那只能考虑一下 dynamic 了,还好,dynamic 只是初次调用的时间稍微长一点点,再次调用就没什么区别
    hez2010
        12
    hez2010  
       2022 年 8 月 7 日 via Android
    interface ISinger
    {
    void Add(object t);
    }

    interface ISinger<T> : ISinger
    {
    void Add(T t);
    }

    class Singer<T> : ISinger<T>
    {
    public void Add(T t) { ... }

    // 这里显式实现接口确保该方法不会直接公开暴露在 Singer<T> 的成员中
    void ISinger.Add(object t) { Add((T)t); }
    }

    试试这样呢?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3457 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 01:17 PVG 09:17 LAX 17:17 JFK 20:17
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86