c# - 如何仅将特定的通用对象传递给方法,该方法将第一个 T 作为派生 T
问题描述
考虑这个代码示例:
我们在解决方案中对我们的 UI 系统进行了抽象:
public abstract class Frame: IFrame {...}
public abstract class Frame<T> : Frame, IFrame<T> {...}
public abstract class Modal:Frame {...}
public abstract class Modal<T>:Modal,IFrame<T> {...}
...
新的模态类可以声明为:
public class MyModal : Modal<T> {...}
其中 T - 数据结构(或类)用于实现具有某些值的模态。
为了预初始化、调整和显示这些 UI,我们使用静态类,其中包含以下方法:
public static T ShowFrame<T>(params) where T : class, IFrame
public static T ShowFrame<T,TK>(TK data, params) where T : class, IFrame<TK>
所以现在,为了显示 MyModal,我们只需调用:
A.ShowFrame<MyModal>(...);
并使用数据:
A.ShowFrame<MyModal, MyModalData>(new MyModalData(...));
问题是,我们如何将强类型数据作为TK传递?我们可以这样写:A.ShowFrame<MyModal>(new AnyClassInSolution(...));
这是不正确的用例。
在当前系统中用户可以传递不正确的数据,这不会做任何事情,但是我们要避免这种用例并防止长写,例如:
A.ShowFrame<MyModal>(new MyModalData(...));
代替
A.ShowFrame<MyModal, MyModalData>(new MyModalData(...));
并且也TK
只能是 T 的数据类型。
我正在考虑制作一个带有对“A”的回调的包装器,它将派生出流畅的 api 和 split 的功能Show<TFrame>
以及Set(data)
任何其他想法,关于如何在一种方法中直接实现它?
编辑:
需要注意的重要一点是,我们尝试使用 IData (或类似的)接口来导出所有数据,而public static T ShowFrame<T,TK>(TK data, params) where T : class, IFrame<TK>
不是public static T ShowFrame<T>(IData data, params) where T : class, IFrame
这解决了可用性问题:没问题A.ShowFrame<MyModal>(new MyModalData(...));
!
但是这里的问题——我们要支持struct
和class
数据输入。(请参阅结构接口装箱/拆箱问题)并且未解决不正确的数据用例。
解决方案
引入第二个IFrame
后代并将数据绑定和非数据绑定类明确分离到两个不同的继承树中可能会提供额外的安全级别。考虑一下:
public interface IFrameNoData : IFrame { … }
public interface IFrame<T> : IFrame { … }
public abstract class FrameNoData : IFrameNoData { … }
public abstract class ModalNoData : FrameNoData {...}
… other abstract classes remain the same …
public class MyModalNoData : MyModal { … }
然后ShowFrame
重载将清楚地区分数据绑定和非数据绑定后代:
public static T ShowFrame<T>() where T : class, IFrameNoData
public static T ShowFrame<T,TK>(TK data) where T : class, IFrame<TK>
像这样使用:
A.ShowFrame<MyModalNoData>(); // legal
A.ShowFrame<MyModal>(new MyModalData(), …); // legal
A.ShowFrame<MyModalNoData>(new MyModalData(), …); // illegal
A.ShowFrame<MyModal>(); // illegal
但是,此解决方案可能违反您可能需要的继承自由。我还会考虑以下类型的验证:
- 运行时:为类型参数添加类型检查,例如一些东西
(typeof(IFrame<TK>)).IsAssignableFrom(typeof(T))
; - 编译时:添加一个基于 Roslyn 的自定义代码检查,该检查将捕获对
ShowFrame
推荐阅读
- android - 在这一点上我有一个例外
- excel - 使用变量来表示范围内的列字母
- java - Picasso 无法应用于给定类型错误 Android Studio
- android - arduino和android之间通过蓝牙进行数据传输。NPE的问题
- r - 如何在ggplot中控制没有边距的图表区域高度?
- sql - SELECT ANY TABLE 权限在 Oracle 中如何工作?
- excel - VBA - 从 XLSX 中删除可以在单元格中找到特定文本的行
- java - 是否可以在@WebInitParam 中动态获取值?
- angular - To call different dialog window based on the button present in the component
- apache-spark - 在 YARN 中启用 CPU 调度真的会改善 Spark 中的并行处理吗?