当泛型类型未知时,将Object转换为泛型类

时间:2010-08-05 17:13:39

标签: c# silverlight generics

在Silverlight项目中,我定义了以下类。

public class ThemeResource<T>
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Type Type { get { return typeof(T); } }
    public string TypeName { get { return Type.FullName; } }
    public T Resource { get { return (T)Application.Current.Resources[this.Name]; } }
}

在我的代码隐藏中使用了几个列表。

public List<ThemeResource<SolidColorBrush>> BrushResources { get; set; }
public List<ThemeResource<Color>> ColorResources { get; set; }
public List<ThemeResource<FontFamily>> FontNameResources { get; set; }
public List<ThemeResource<Thickness>> ThicknessResources { get; set; }
public List<ThemeResource<Double>> FontSizeResources { get; set; }
public List<ThemeResource<Style>> TextStyleResources { get; set; }

我的视图有几个列表框绑定到列表,就像这样。

<UserControl x:Name="ThemeResourcesPage" ...>
    <ListBox Style="{StaticResource BrushResourceListBoxStyle}"
                ItemsSource="{Binding ElementName=ThemeResourcesPage, Path=BrushResources}"
                SelectionChanged="ListBox_SelectionChanged" />
</UserControl>

我希望在我的代码隐藏中有一个SelectionChanged事件处理程序,我的所有列表都使用它来显示有关所选ThemeResource的详细信息。我的问题是SelectionChangedEventArgs'RelectedItems是一个对象列表,ListBox上的SelectedItem属性是一个对象。

这不起作用:

private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count != 1)
        return;

    var tr = (ThemeResource<T>)e.AddedItems[0];
    var msg = string.Format("Name: {0}\nType: {1}\nDescription: {2}",
                            tr.Name, tr.TypeName, tr.Description);
    MessageBox.Show(msg);
}

如何在不知道T是什么的情况下将对象转换为ThemeResource?

1 个答案:

答案 0 :(得分:1)

你做不到。通常的解决方案是这样的:

public interface IThemeResource
{
    public string Name { get; }
    public string Description { get; }
    public string TypeName { get; }
}

public class ThemeResource<T> : IThemeResource
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Type Type { get { return typeof(T); } }
    public string TypeName { get { return Type.FullName; } }
    public T Resource { get { return (T)Application.Current.Resources[this.Name]; } }
}

然后,您可以传递IThemeResource并获取其属性,无论其具体的泛型类型如何。

(也许你的问题承认了一些其他更简单的解决方案,而不是使用泛型类型,但我会把它留给其他人提出来。)