C#通用转换器

5

我有一个转换器,能够在选择项和通用的 List<MyType> 之间进行转换。

public class SelectedTiposDocsToList : BaseConverter, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var Selecteditems = value as IList;
        List<MyType> MyTypeList = Selecteditems.Cast<MyType>().ToList();
        return MyTypeList;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
} 

现在这对我来说是一个常见的任务,我想扩展这个类以允许使用一般类型,像这样做也许可以吗?
public class SelectedTiposDocsToList : BaseConverter, IValueConverter
{
    public object Convert<T>(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var Selecteditems = value as IList;
        List<T> MyTypeList = Selecteditems.Cast<T>().ToList();
        return MyTypeList;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
} 

这是否可行? 如果是,如何在XAML上使用这种转换器?


我会说不,因为您将不再实现接口。不过这是一个有趣的问题!您能否将类型传递给参数变量? - BradleyDotNET
也许吧。但是我在这方面没有太多经验。而且不知道如何使用XAML语法将更多参数传递给转换器。 - Juan Pablo Gomez
我同意Bradley的观点。然而,你可以让转换器调用一个使用泛型的服务。没有任何阻止这样做的限制。将类传递给转换器的参数即可。 - Gayot Fow
@GayotFow。也许需要一些示例来看看怎么做? - Juan Pablo Gomez
@JuanPabloGomez,这里有一篇来自传奇人物Skeet的精彩回答,获得了97个赞,讲述如何在运行时调用带有类型参数的泛型方法。链接在此:https://dev59.com/MXRC5IYBdhLWcg3wW_pk - Gayot Fow
2个回答

4
不,这不是一个有效的IValueConverter实现。但是你可以在参数上传递一个类型:
{Binding MyVariable, Converter={StaticResource SelectedTiposDocsToList}, ConverterParameter={x:Type local:MyType}}

然后使用 SelectConvert.ChangeType 方法: MSDN

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    var Selecteditems = value as IList;
    var MyTypeList = Selecteditems.Cast<object>().Select((i) => System.Convert.ChangeType(i, parameter as Type)).ToList();
    return MyTypeList;
}

已验证可以在VS 2013上编译。


1
这可以通过一些反射来完成:使用 Type.MakeGenericType 获取类型,使用 Activator.CreateInstance 调用 正确的构造函数,并使用 MethodInfo.MakeGenericMethod 将参数传递给 Cast
public Type ConvertType { get; set; }
public object Convert(object value, Type targetType, object parameter,
                      System.Globalization.CultureInfo culture)
{
    var type = typeof(List<>).MakeGenericType(ConvertType);
    var methodInfo = typeof(Enumerable).GetMethod("Cast");
    var genericMethod = methodInfo.MakeGenericMethod(ConvertType);
    var convertTypeList = Activator.CreateInstance(type,
                    genericMethod.Invoke(null, new[] { value }));
    return convertTypeList;
}

你可以在XAML中使用x:Type指定类型。
<myns:SelectedTiposDocsToList x:Key="Conv" ConvertType="{x:Type myns:MyType}" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接