首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将类型的对象添加到适合泛型类型的对象的通用解决方案

将类型的对象添加到适合泛型类型的对象的通用解决方案
EN

Stack Overflow用户
提问于 2018-10-22 21:43:35
回答 1查看 59关注 0票数 0

我觉得接口(相反?)变化是答案,但无法找到正确的解决方案。

让我们上这几门课:

代码语言:javascript
复制
public abstract class Fruit { }
public class Banana : Fruit { }
public class Apple : Fruit { }

public abstract class Picture { }
public class FruitPicture<T> : Picture, Contravariant<T>, Covariant<T> where T : Fruit
{
    T myFruit = null;

    public Type GetFruitType() { return typeof(T); }

    public void AddFruit(T fruit) { this.myFruit = fruit; }
}

public interface Contravariant<in T> { void AddFruit(T model); }
public interface Covariant<out T> { Type GetFruitType(); }

我的情况是:

  • 我已经初始化了香蕉和苹果的集合,如这两个(但我可以使用另一个): Fruit[] myFruits =新Fruit2 {新香蕉(),新苹果() };
  • 我有一组图片,如这两幅: Picture[] myPictures =新Picture2 {新的FruitPicture(),新的FruitPicture(),};

现在,我试图做一件非常简单的事情,但是以一种通用的方式,这意味着我希望避免在每次发现新的结果时必须更改代码的任何开关/ifs,并且新的FruitPicture可能出现在我想要的集合=>中,从我的集合到正确的FruitPicture类型。我几乎可以更改任何逻辑,但我希望保留泛型的FruitPicture类。

我得到的最接近的是:

代码语言:javascript
复制
foreach(Picture curPicture in myPictures)
{
    foreach (Fruit curFruit in myFruits)
    {
        Covariant<Fruit> fruitType = (Covariant<Fruit>)curPicture;
        if (curFruit.GetType() == fruitType.GetFruitType())
        {
            // what now?
        }
    }
}

谢谢,先生。(开玩笑的;有点)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-22 22:02:16

因为您所面临的问题是您想要确保编译时类型的安全性,但在运行时才知道类型,所以可以使用dynamic将决策推送到运行时。我不一定建议这样做,只是说它会起作用。

我将Covariant接口更改为不需要泛型,因为它没有使用类型参数。我将AddFruit重命名为SetFruit,因为它没有添加任何内容,而是替换了。

代码语言:javascript
复制
foreach (var fruit in myFruits) {
    foreach (var picture in myPictures) {
        if (picture is Covariant cov) {
            if (cov.GetFruitType() == fruit.GetType())
                ((dynamic)picture).SetFruit(Convert.ChangeType((dynamic)fruit, cov.GetFruitType()));
        }
    }
}

需要(dynamic) ChangeType,因为fruit的类型是Fruit,它不是传递给任何SetFruit的有效类型。它必须是动态的,因为ChangeType的静态编译时类型是object,这也不是任何SetFruit的有效类型。

或者,如果您将决定推到FruitPicture中,会怎么样?

代码语言:javascript
复制
public interface Covariant {
    void SetCompatibleFruit(Fruit f);
}

public class FruitPicture<T> : Picture, Covariant where T : Fruit {
    T myFruit = null;

    public void SetCompatibleFruit(Fruit f) {
        if (f is T tf)
            this.myFruit = tf;
    }
}

然后,如果可以的话,只需让每个Covariant picture设置fruit

代码语言:javascript
复制
foreach (var fruit in myFruits) {
    foreach (var picture in myPictures) {
        if (picture is Covariant cov)
            cov.SetCompatibleFruit(fruit);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52938167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档