2015-09-22 38 views
0

给出下面的代码,当我创建一个字典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()); 
+0

类型'dataservice_FourSideShape '不能转换为'ICrud '。它可转换为'ICrud ',但仅仅因为'FourSideShape'是一个'IShape',并不意味着'ICrud '可转换为'ICrud '。 – Enigmativity

+3

'ICrud'上的'T'必须是co-variant(将'in'改为'out'),以便'someA '可以转换为'ISomeA ',但是,这意味着你不能有一种方法, T'作为参数,只返回'T' – Rob

+0

@Rob这应该是一个答案,对于有类似问题的其他人来说更容易找到答案。 –

回答

2

TICrud必须同时变种(其他城市inout),为了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);并删除模板?

+0

不完全解决问题,因为我需要一个保存方法 – Victor