键入泛型接口

本文关键字:泛型接口 | 更新日期: 2023-09-27 18:34:54

我正在尝试创建两个接口层次结构,一个用于业务模型对象,一个用于UI。 我知道层之间的松散耦合很重要,但应用程序的一部分将需要绘制图表,所以我需要模型对象随时可用于其相应的图形表示,并且我有一个用于模型对象的通用层保存接口。

通用类库代码:

public interface IBase {}
public interface IBookObject : IBase {}
public interface ITapeObject : IBase {}
public class Book : IBookObject {}

图形层代码:

public interface IModelObject<T> 
{
  T ModelObject { get; set; } // might be a book or tape , etc
}
public class GraphicObject<T> : IModelObject<T>
{
  public T ModelObject { get; set; }
}

代码使用:

IBookObject bk = new Book();
var go = new GraphicObject<IBookObject>(); // will fail later
//var go = new GraphicObject<IBase>(); // will succeed later
go.ModelObject = bk;
if (go is IModelObject<IBase>) // can't use is IModelObject<IBookObject>
                               // as go might be GraphicObject<ITapeObject>
{
  Debug.WriteLine("Success");
}

因此,如果我想测试 IBase(然后访问 ModelObject(,我必须确保原始对象是使用 IBase 创建的,而不是派生接口,这似乎是以后出现错误的原因。 我的问题是:

1(我在做什么可怕的事情吗?!:)我可能忽略了一个更好的方法。

2(如果做不到这一点,有没有办法使用新的逆变C#4技术对从IBase派生的任何接口进行IS线测试? 或者,我认为如果IBook不是从IBase继承的,但是Book(和Tape(分别实现了IBook和IBase,那么它会起作用。

3(如果做不到这一点,有没有办法防止GraphicObject<IBookObject>()GraphicObject<ITapeObject>()的建设?

谢谢!

键入泛型接口

这行得通吗?

public interface IBase { }
public interface IBookObject : IBase { }
public interface ITapeObject : IBase { }
public class Book : IBookObject { }
public interface IModelObject
{
    IBase ModelObject { get; set; } // might be a book or tape , etc
}

public class GraphicObject<T> : IModelObject
    where T: class, IBase
{
    public T ModelObject { get; set; }
    #region IModelObject Members
    IBase IModelObject.ModelObject
    {
        get
        {
            return ModelObject;
        }
        set
        {
            ModelObject=value as T;
        }
    }
    #endregion
}
class Program
{
    static void Main(string[] args)
    {
        IBookObject bk=new Book();
        var go=new GraphicObject<IBookObject>(); // will fail later
        //var go = new GraphicObject<IBase>(); // will succeed later
        go.ModelObject=bk;
        if(go is IModelObject) // can't use is IModelObject<IBookObject> as go might be GraphicObject<ITapeObject>
        {
            Debug.WriteLine("Success");
        }
    }
}