泛型类型的转换失败 [英] cast of generic type fails

查看:149
本文介绍了泛型类型的转换失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法将泛型转换为另一个泛型,除此之外,转换应该是有效的。

我想归档的内容简而言之( MyModel 执行 IModel MyImplementation 执行 IImplementation $ b

  IImplementation< IModel> implementation = new MyImplementation< MyModel>(); 
Assert.IsNull(实现为IImplementation< IModel>);

这有点令人困惑,因为该类型应该是有效的。



完整的概念模型:

  interface IModel {} 

class MyModel: IModel {}

interface IImplementation< TModel>其中TModel:IModel {}

class MyImplementation< TModel> :IImplementation< TModel>
where TModel:IModel {}

public void CallRegister()
{
var implementation = new MyImplementation< MyModel>();
var instance = CastModel(implementation);
Assert.IsNotNull(instance); //这个断言失败!
}

private object CastModel< TModel>(IImplementation< TModel>实现)其中TModel:IModel
{
返回实现为IImplementation< IModel>;
}

我需要这个转换才能保存多个 IImplementation s到相同的 Dictionary< Type,IImplementation< IModel>> ,其中的密钥是通过执行 typeof (TModel的)
要做到这一点类型安全,我不想使用字典<类型,对象>




  • 演员为什么失败?有没有额外的资源呢?它与类型受限C#通用的无效投射类似的问题 ,但没有解释为什么只是它不起作用。
  • 如果这种类型的转换不可行,那么如上所述归档类似于字典的功能的最佳方式是什么? ?


解决方案

这种转换不允许有很好的理由。我们举一个问题更为明显的例子。我们有类动物 Cat:Animal Dog:Animal 。现在让我们来做这件事:

 列表< Animal> list = new List< Cat>(); //乍一看似乎是可能的。 
//现在出现这个问题:
list.Add(new Dog()); //似乎也可能。

但是请稍等!这份名单实际上是猫的名单!我们正在尝试添加一条狗。甚至将新Animal()添加到 list 中,静态类型为 List< Animal> $ b

因此,两种类型 T 和<$即使 A B T 在C#

您需要另一种方法。




你可以做的是用泛型类型约束的泛型方法将你的字典封装在类中。

  public class MyImplementationDict 
{
private只读字典< Type,object> _internalDict = new Dictionary< Type,object>();

public void Add< T>(IImplementation< T> item)
其中T:模型
{
_internalDict.Add(typeof(T),item);
}

...
}


I am unable to cast a generic type to another generic type, besides the cast should be valid

What I want to archive is in short (for MyModel implementing IModel, and MyImplementation implementing IImplementation):

IImplementation<IModel> implementation = new MyImplementation<MyModel>();
Assert.IsNull(implementation as IImplementation<IModel>);

This is a bit confusing, as the type should be valid.

Complete conceptual model:

interface IModel {}

class MyModel : IModel {}

interface IImplementation<TModel> where TModel : IModel { }

class MyImplementation<TModel> : IImplementation<TModel>
    where TModel : IModel { }

public void CallRegister()
{
    var implementation = new MyImplementation<MyModel>();
    var instance = CastModel(implementation);
    Assert.IsNotNull(instance); //this assert fails!
}

private object CastModel<TModel>(IImplementation<TModel> implementation) where TModel : IModel
{
    return implementation as IImplementation<IModel>;
}

I need this cast to enable me to save multiple IImplementations to the same Dictionary<Type, IImplementation<IModel>>, where the key is obtained by doing typeof(TModel). To do this type safe I don't want to use a Dictionary<Type, object>.

解决方案

This kind of conversion is not allowed for good reasons. Let's take an example where the problem is more obvious. We have the classes Animal, Cat : Animal and Dog : Animal. Now let's do this:

List<Animal> list = new List<Cat>(); // Seems to be possible at first glance.
// An now comes the problem:
list.Add(new Dog());    // Seems to be possible as well.

But wait! The list is in reality a list of cats! And we are trying to add a dog. Even adding new Animal() to list, which is statically typed as List<Animal>, would not work.

Therefore two types T<A> and T<B> are not assignment compatible in C#, even if A and B are!

You need another approach.


What you can do is to wrap your dictionary in a class with a generic method having a generic type constraint.

public class MyImplementationDict
{
    private readonly Dictionary<Type, object> _internalDict = new Dictionary<Type, object>();

    public void Add<T>(IImplementation<T> item)
        where T : IModel
    {
        _internalDict.Add(typeof(T), item);
    }

    ...
}

这篇关于泛型类型的转换失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆