从泛型类型中检索数据

时间:2016-02-05 11:59:22

标签: c# generics

我有以下界面,可以通过自定义控件和表单实现:

public interface IThemeable<T> where T : ITheme
{
    T Theme { get; set; }

    void ChangeTheme(); // Calls ThemeChangedEvent
}

ITheme是所有主题都继承自的接口:

public interface ITheme : ICloneable
{
    Color ThemeColor { get; set; }
}

如果Parent也是IThemeable,我希望ThemeColor个组件能够继承父主题IThemeable,因此我创建了一个接口来提供此功能:

public interface IThemeableComponent
{
    bool InheritTheme { get; set; }
    ITheme ParentTheme { get; set; }

    void InitializeTheme();
}

InitializeTheme内部是我要设置ParentTheme的位置,所以我理想的是要检查组件的父级是否继承自IThemeable,如果是,请设置ParentTheme到父母的主题。但是,因为IThemeable需要通用类型,所以我不能这样做:

// Expander.cs - class Expander : ContainerControl, IThemeable<ExpanderTheme>, IThemeableComponent

private bool _inheritTheme;
public bool InheritTheme
{
    get
    {
        return _inheritTheme;
    }
    set
    {
        // Check whether the parent is of type IThemeable
        _inheritTheme = Parent.GetType().GetGenericTypeDefinition() == typeof (IThemeable<>) && value;
    }
}

public ITheme ParentTheme { get; set; }

public void InitializeTheme()
{
    Theme = Themes.ExpanderDefault.Clone() as ExpanderTheme;

    if (Parent.GetType().GetGenericTypeDefinition() == typeof (IThemeable<>))
    {
        ParentTheme = (Parent as IThemeable<>).Theme; // Type argument is missing
    }
}

有没有办法可以实现我的目标?或者如果没有,是否有其他方法?

修改

IThemeable是通用的。实现成员应该具有扩展ITheme而不是ITheme本身的指定主题,原因有两个:

  1. 使用设计师更改主题。他们还使用编辑器来更改主题。如果使用ITheme,设计人员将无法确定正在使用的实现主题。

  2. 代码需要了解有关主题的更多信息才能正确呈现组件,因为每个主题都有自己独特的属性(例如,FormTheme有Color ControlBoxHoverColor)。如果使用ITheme,我需要将其转换为首选类型,而不是使用如下代码:

  3. -

    // ThemedForm.cs - class ThemedForm : Form, IThemeable<FormTheme>
    
    private FormTheme _theme;
    
    [DisplayName("Theme")]
    [Category("Appearance")]
    [Description("The Theme for this form.")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [Editor(typeof(ThemeTypeEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public FormTheme Theme
    {
        get { return _theme; }
        set
        {
            _theme = value;
            ChangeTheme();
        }
    }
    

1 个答案:

答案 0 :(得分:1)

由于ParentTheme只是ITheme,因此以下应该可以解决问题:

ParentTheme = (ITheme)Parent.GetType().GetProperty("Theme").GetValue(Parent);