c# - 泛型类的泛型类型的 C# 育儿?对我来说太复杂了,无法对问题形成更合适的问题:|
问题描述
我无法弄清楚如何使用泛型类型来解决我的问题。另外我不知道如何简短地描述我的问题,所以我将简化版本的问题作为扩展解释。
我正在制作用于切换质量的系统,在不同类型的“组件”类之间转换质量级别。我有像这样的基类:
public abstract class QualityLevel_Base
{
public bool Enabled = true;
public virtual void Transition(QualityLevel_Base a, QualityLevel_Base b, double value)
{
if (value >= 1) Enabled = b.Enabled; else if (value <= 0) Enabled = a.Enabled;
}
protected static double Lerp(double a, double b, double t) { return (1 - t) * a + t * b; }
}
然后我像这样继承它:
public sealed class QualityLevel_LightSource : QualityLevel_Base
{
public double Intensity;
public double Range;
public int ShadowsQuality;
public override void Transition(QualityLevel_Base a, QualityLevel_Base b, double value)
{
QualityLevel_LightSource la = a as QualityLevel_LightSource; // One part of my problem - avoid casting
QualityLevel_LightSource lb = b as QualityLevel_LightSource;
base.Transition(a, b, value);
Intensity = Lerp(la.Intensity, lb.Intensity, value);
/* etc... */
}
}
然后我想管理其他类中的质量级别,并能够将设置应用于所需的组件类。所以我有基类来管理任何质量级别:
public abstract class QualityManager_Base
{
public Component SourceComponent { get; protected set; }
public List<QualityLevel_Base> QualityLevels { get; protected set; }
public virtual void Initialize(Component component, int qualityLevelsCount)
{
QualityLevels = new List<QualityLevel_Base>();
SourceComponent = component;
AutoQualitySettings(qualityLevelsCount);
}
public virtual void AutoQualitySettings(int qualityLevelsCount) { }
public virtual void ApplyQualitySettings(QualityLevel_Base qualityLevel)
{
SourceComponent.Enabled = qualityLevel.Enabled;
}
}
我为 LightSource 继承了它,例如:
public sealed class QualityManager_LightSource : QualityManager_Base
{
public LightSource Light { get; private set; }
public override void Initialize(Component component, int qualityLevelsCount)
{
LightSource light = component as LightSource; // Another situation when I would like to avoid casting
Light = light;
base.Initialize(light, qualityLevelsCount);
}
public override void AutoQualitySettings(int qualityLevelsCount)
{
for (int i = 0; i < qualityLevelsCount; i++)
{
QualityLevel_LightSource lightSettings = new QualityLevel_LightSource();
lightSettings.Intensity = Light.Intensity;
lightSettings.Range = Light.Range;
lightSettings.ShadowsQuality = i / qualityLevelsCount;
if (i == qualityLevelsCount - 1) lightSettings.Enabled = false;
}
}
public override void ApplyQualitySettings(QualityLevel_Base qualityLevel)
{
base.ApplyQualitySettings(qualityLevel);
// To my Question: I want to use generic type to avoid casting
QualityLevel_LightSource lightSettings = qualityLevel as QualityLevel_LightSource;
Light.Intensity = lightSettings.Intensity;
Light.Range = lightSettings.Range;
Light.ShadowsQuality = lightSettings.ShadowsQuality;
}
}
实际上,我设法在这个问题上使用了泛型类型,例如:
public abstract class QualityLevel_Base<T> where T : QualityLevel_Base<T> { /*...*/ }
public class QualityLevel_LightSource : QualityLevel_Base<QualityLevel_LightSource> { /*...*/ }
public abstract class QualityManager_Base
{
public List<QualityLevel_Base> QualityLevels; // Would like to define it like that but I have to do it
// like that:
public abstract class QualityManager_Base<T> where T : QualityLevel_Base<T>
{
public List<QualityLevel_Base<T>> QualityLevels;
}
然后做这样的事情会导致错误:
public abstract class QualityManager_Base<T> where T : QualityLevel_Base<T>
{
public List<QualityLevel_Base<T>> QualityLevels;
public virtual void AddComponentForQualityManager(Component comp)
{
if (QualityLevels == null) QualityLevels = new List<QualityLevel_Base<T>>();
LightSource light = comp as LightSource;
if (light != null)
{
QualityManager_LightSource lightManager = new QualityManager_LightSource();
QualityLevels.Add(lightManager); // Then I Can't do this because: "cannot convert from 'QualityManager_LightSource' to 'QualityLevel_Base<T>' "
}
/* ... */
}
}
“无法从 'QualityManager_LightSource' 转换为 'QualityLevel_Base'”
我的系统中当然还有更多事情要做,它只是一个非常简化的版本来定义我的问题:我怎样才能避免强制转换类,我怎样才能正确地做到这一点?谢谢!
解决方案
推荐阅读
- c# - 为什么 Double.ToString("F1") 在 .NET Core 3.1 中的行为不同?
- python - 从 Pandas 导出到 excel 时遇到问题
- android - 获取捕获的图像 Android Kotlin 的图像 URI
- python - 使用 pandas 确定需要多少之前的行才能求和到阈值
- pandas - 通过部分匹配合并两个数据框
- laravel - 使用 Yajra Datatable 在 Laravel Datatable 列中添加列值总和的行
- spring-boot - Spring Boot 重复日志
- python - 在 spark sql 中动态转义字符
- reactjs - React 本机调试器不会显示我的 redux 状态,它会一直显示其他状态
- proguard - 使用 ProGuard 和 NavigationComponent 安全参数进行混淆