c# - 在 C# 泛型中传递“this”在没有强制转换的情况下不起作用
问题描述
我尝试了谷歌搜索和stackoverflow,但找不到我的具体问题的答案(甚至是有限的泛型知识)
所以我在这里发帖希望得到答案。
这是我的课
public abstract class AThemeableControl<TManager, TControl>
where TManager:AManagerTheme<TManager, TControl>
where TControl:AThemeableControl<TManager, TControl>
{
public abstract void UpdateTheme(TManager managerTheme);
}
这是经理班
public abstract class AManagerTheme<TManager, TControl>
where TManager:AManagerTheme<TManager, TControl>
where TControl:AThemeableControl<TManager, TControl>
{
public TControl[] ThemableControls;
virtual public void ApplyTheme()
{
for (int i = ThemableControls.Length-1; i >= 0; i--)
{
ThemableControls[i].UpdateTheme(this); //ERROR HERE
}
}
}
所以我可以通过类型转换来解决这个错误
ThemableControls[i].UpdateTheme((TManager) this);
但我想知道没有类型转换的解决方案,我希望这是可能的。
解决方案
你不能移除演员表,因为这样做是不安全的。这是演员抛出的示例:
using System;
public abstract class AManagerTheme<TManager, TControl>
where TManager : AManagerTheme<TManager, TControl>
where TControl : AThemeableControl<TManager, TControl>
{
public TControl[] ThemableControls;
public virtual void ApplyTheme()
{
for (int i = ThemableControls.Length - 1; i >= 0; i--)
{
ThemableControls[i].UpdateTheme((TManager) this);
}
}
}
public abstract class AThemeableControl<TManager, TControl>
where TManager : AManagerTheme<TManager, TControl>
where TControl : AThemeableControl<TManager, TControl>
{
// Empty implementation; irrelevant for the question.
public void UpdateTheme(TManager managerTheme) {}
}
public class NormalTheme : AManagerTheme<NormalTheme, NormalControl>
{
}
public class NormalControl : AThemeableControl<NormalTheme, NormalControl>
{
}
public class EvilTheme : AManagerTheme<NormalTheme, NormalControl>
{
}
public class Test
{
static void Main()
{
var theme = new EvilTheme
{
ThemableControls = new[] { new NormalControl() }
};
theme.ApplyTheme();
}
}
这是您要防止的:
public class EvilTheme : AManagerTheme<NormalTheme, NormalControl>
...但你不能用 C# 泛型来表达。(我在早期版本的 Protocol Buffers 中遇到过同样的事情,其中每个“消息”类型都有相应的“构建器”类型。)C# 类型系统还不够丰富来表达这一点。
您可能想检查抽象类构造函数中的有效性,以便至少您知道强制转换稍后会起作用。但是你不能避免在某处进行投射或使用不同的TManager
地方。
推荐阅读
- swift - 在另一个 ViewController (macOS) 中调用函数
- regex - 通过 RegEx 从字符串获取价格(仅金额,无货币标签,无特殊字符)
- asp.net-core - 从没有 xmlns:xsi 和 xmlns:xsd 的 ASP .NET Core Web API 返回完整的 XML 响应
- javascript - 未捕获的 ReferenceError:Electron BrowserWindow 中未定义要求
- mysql - 尝试将 TEXT 列 3k+ 大行中的内容(值)复制或以某种方式移动到同一数据库中的另一个表,但没有成功
- c++ - 试图在 cmake 中包含 glfw 库
- python - 计算数组中列出的项目的票数_python
- pine-script - 为 sma() 和 ema() 声明一个变量
- c++ - GNU MP:无法分配内存(大小=4294959136)
- c++ - GCC 的 C++ 犰狳线性代数库链接器错误