没有强制转换,在C#泛型中传递“ this”将不起作用

时间:2019-02-20 16:25:28

标签: c#

我尝试使用谷歌搜索和stackoverflow,但是找不到我特定问题的答案(甚至是有限的泛型知识)

所以我在这里发布,希望得到答案。

这是我的课程

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>

<div id="app">
  <v-form v-model="valid" ref="form" class="px-3">
    <v-text-field label="First Name" v-model="firstname" :rules="inputRules"></v-text-field>
    <v-text-field label="Last Name" v-model="lastname" :rules="inputRules"></v-text-field>
    <v-text-field label="Email" v-model="email"></v-text-field>
    <v-btn :loading="loading" flat class="success mx-0 mt-3" @click="submit">Create Person</v-btn>
  </v-form>
</div>

这是经理班

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           
        }           
    }
}

但是我想在没有类型转换的情况下了解解决方案,这是我希望的。

1 个答案:

答案 0 :(得分:9)

您无法删除演员表,因为这样做是不安全的。这是演员表抛出的例子:

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#泛型来表达这一点。 (在早期版本的协议缓冲区中,我也遇到过类似的情况,其中每个“消息”类型都有一个对应的“构建器”类型。)C#类型系统不足以表达它。

您可能要检查抽象类构造函数中的有效性,以便至少知道转换将在以后工作。但是您不能避免在某个地方使用其他TManager来投射