简体   繁体   English

当通用类型未知时,将对象强制转换为通用类

[英]Cast an Object to a generic class when the generic type isn't known

In a Silverlight project, I've got the following class defined. 在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]; } }
}

With several lists using the class in my code-behind. 在我的代码后面有几个使用该类的列表。

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

And my view has several list boxes bound to the lists, like this. 我的视图中有几个绑定到列表的列表框,就像这样。

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

I want to have a single SelectionChanged event handler in my code-behind that all of my lists use to display details about the ThemeResource that was selected. 我想在我的代码中有一个SelectionChanged事件处理程序,所有我的列表都用来显示有关所选ThemeResource的详细信息。 My problem is that the SelectionChangedEventArgs' AddedItems is a list of objects, and the SelectedItem property on the ListBox is an object. 我的问题是SelectionChangedEventArgs的AddedItems是对象列表,而ListBox上的SelectedItem属性是对象。

This won't work: 这行不通:

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

How do I cast the object to ThemeResource without knowing what T will be? 如何在不知道T是多少的情况下将对象投射到ThemeResource?

You can't. 你不能 The usual solution would be something like this: 通常的解决方案是这样的:

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

Then you can pass around IThemeResource s and get their properties regardless of their concrete generic type. 然后,您可以绕过IThemeResource并获取其属性,而不管其具体的泛型类型如何。

(Perhaps your problem admits some other, simpler solution than using generic types for this at all, but I'll leave that for someone else to come up with.) (也许您的问题接受了一些根本不比使用泛型类型更简单的解决方案,但我将其留给其他人提出。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM