有机会合法投吗?

发布于 2024-10-18 17:35:55 字数 963 浏览 5 评论 0原文

这是我第一次在这里发布问题,所以提前感谢任何能帮助我的人(也许还有其他人)。

今天,我对 C# 4 中的协变和逆变感到困惑,但我真的看不到任何做我想做的事情的可能性。 注意:所有这些都不是为了解决特定问题,但我想知道是否有任何合法的方法(C# 4 中的全新 co/contra-variance)来解决它。 所以,不要疯狂......

这里是示例代码:

public interface IBase<in T>
{
    T GetValue();
    ...
}


public class Readable<T> : IBase<T>
{
    public T GetValue() {/* */}
    ...
}


public class Writeable<T> : IBase<T>
{
    public T GetValue() {/* */}
    public void SetValue(T value) {/* */}
    ...
}


public class Program
{
    private List<IBase<object>> _collection = new List<IBase<object>>();


    public static void Main()
    {
        var p = new Program();

        p._collection.Add(new Readable<bool>());    //not allowed
    }
}

该集合应该能够托管任何 IBase 衍生品,即任何 T 的衍生品。 当然,我可以使用非泛型集合或列表,然后游戏就结束了。 另一个想法是有一个更通用的接口IBaseCore,然后IBase继承自。 我的问题是:如果没有这些技巧,我可以实现拥有 IBase 的集合并添加任何 IBase 的项目吗?

谢谢大家。

This is my very first time to post a question here, so thanks in advance to anyone will help me (and maybe others).

Today I've been puzzled with covariance and contravariance in C# 4, but I really can't see any possibility to do what I would.
NOTE: all that is NOT to solve a specific problem, but I'd like to know if there's any legal way (brand-new co/contra-variance in C# 4) to solve it.
So, don't get crazy...

Here the sample code:

public interface IBase<in T>
{
    T GetValue();
    ...
}


public class Readable<T> : IBase<T>
{
    public T GetValue() {/* */}
    ...
}


public class Writeable<T> : IBase<T>
{
    public T GetValue() {/* */}
    public void SetValue(T value) {/* */}
    ...
}


public class Program
{
    private List<IBase<object>> _collection = new List<IBase<object>>();


    public static void Main()
    {
        var p = new Program();

        p._collection.Add(new Readable<bool>());    //not allowed
    }
}

The collection should be able to host any of the IBase derivatives, being them of any T.
Of course I may use a non-generic collection or a List and the game is over.
Another idea is having a more common interface IBaseCore, then IBase inherits from.
My question is: without these tricks may I achieve to have a collection of IBase and add items of any IBase?

Thanks to everyone.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黯然 2024-10-25 17:35:55

编辑:首先,您的方差对于 IBase 是错误的。它应该是out T(协变)而不是in T(逆变)。

这里的问题很简单,泛型协变和逆变不适用于作为类型参数的值类型。因此,您可以添加 Readable,但不能添加 Readable

一种选择是拥有一个非通用基接口:

public interface IBase
{
    object GetValueAsObject();
}

public interface IBase<out T> : IBase
{
    T GetValue();
    ...
}

然后您可以拥有一个 List

EDIT: First things first, your variance is wrong for IBase<T>. It should be out T (covariant) rather than in T (contravariant).

The problem here is simply that generic covariance and contravariance doesn't work with value types as the type arguments. So you could add a Readable<string>, but not a Readable<bool>.

One option is to have a nongeneric base interface:

public interface IBase
{
    object GetValueAsObject();
}

public interface IBase<out T> : IBase
{
    T GetValue();
    ...
}

Then you could have a List<IBase>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文