通用类型兼容性我做错了什么

时间:2015-09-22 01:57:17

标签: c# generics

鉴于以下代码,当我创建字典Dictionary<System.Type, ICrud<IShape>>时,我无法像这样添加到字典中。它不编译Add(typeof(FourSideShape), new dataservice_FourSideShape<FourSideShape>())

我做错了什么?

 public interface ICrud<in T> where T: IShape
    {
        void save(T form);
    }
public class dataservice_Shape<T>  where T : IShape
{
    public void save(T form) {

    }
}


public class dataservice_FourSideShape<T> : ICrud<T> where T : FourSideShape 
{
    public void save(T form)
    {

    }
}

public interface IShape {
    string ShapeName {get;}
}

public abstract class Shape : IShape
{
    public abstract string ShapeName { get; }
}

public class FourSideShape : Shape
{
    public override string ShapeName
    {
        get
        {
            return "FourSided";
        }
    }
}

   Dictionary<System.Type, ICrud<IShape>> services = new Dictionary<System.Type, ICrud<IShape>>();

   // fill the map
   this.services.Add(typeof(FourSideShape), new dataservice_FourSideShape());

1 个答案:

答案 0 :(得分:2)

T上的

ICrud必须是共同变体(将in更改为out),以便将someA<someB>转换为ISomeA<ISomeB> }

但是,这意味着您无法使用T作为参数,只返回T - (您的保存方法无效)。

以下是为什么你不能做你想做的事情的例子:

void Main()
{
    var c = new Crud<Shape>(); //Crud contains a List<Shape>
    c.Save(new Shape());       //Crud.SavedItems is a List<Shape> with one item

    ICrud<IShape> broken = ((ICrud<IShape>)c);
    broken.Save(new AnotherShape()); // Invalid ! 
                                     // Trying to add a 'AnotherShape' to a List<Shape>
}

public interface IShape {
    string ShapeName {get;}
}

public interface ICrud<in T> where T: IShape
{
   void save(T form);
}

public class Shape : IShape {
    public string ShapeName { get; set; }
}

public class AnotherShape : IShape {
    public string ShapeName { get; set; }
}

public class Crud<T> : ICrud<T> where T : IShape
{
    public List<T> SavedItems  = new List<T>();
    public void save(T form)
    {
        //Do some saving..
        SavedItems.Add(form);
    }
}

您必须重新设计代码。也许将void save(T form);更改为void save(IShape form);并删除模板?