为什么不工作这个类型转换器? [英] Why is this TypeConverter not working?

查看:117
本文介绍了为什么不工作这个类型转换器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解为什么下面的代码没有按预期工作;在 TypeDescriptor 根本就没有拿起从属性自定义转换器。我只能假设我做了一个明显的错误,但我无法看到它。



- 编辑 - 这个代码似乎当我在一个控制台上运行它的工作了,自己的,我实际调用从一个更复杂的应用程序中,并从不同的命名空间转换器



- 编辑 - 或者我如何能调试任何建议该TypeDescriptor这样我就可以看看是怎么回事,然后我也许可以回答这个问题我自己



- 编辑 - 这个问题几乎肯定与片不同的是。组件



- 编辑 - 它看起来像这样因为动态加载组件的一些怪癖的不工作 - 这个代码是这样架构的插件下运行

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.Drawing中;
使用System.ComponentModel;

命名MyTest的
{

公共类TestTester
{
公共静态无效的主要(字串[] args)
{
对象v = TypeDescriptor.GetConverter(typeof运算(MyTest.Test))ConvertFromInvariantString(测试)。
}
}

公共类TestConverter:TypeConverter的
{

公众覆盖布尔GetStandardValues​​Supported(ITypeDescriptorContext上下文)
{
返回FALSE;
}

公众覆盖布尔CanConvertFrom(ITypeDescriptorContext背景下,System.Type的sourceType的)
{
如果(sourceType的== typeof运算(字符串)|| base.CanConvertFrom(背景下,sourceType的))
{
返回真;
}
返回base.CanConvertFrom(上下文,sourceType的);
}

公众覆盖布尔CanConvertTo(ITypeDescriptorContext背景下,类型destinationType)
{
如果(destinationType == typeof运算(测试)|| base.CanConvertTo(destinationType) )
{
返回真;
}
返回base.CanConvertTo(背景下,destinationType);
}

公共覆盖对象ConvertFrom(ITypeDescriptorContext背景下,System.Globalization.CultureInfo文化,对象的值)
{
如果(value.GetType()== typeof运算(字符串))
{
测试T =新的测试();
t.TestMember =值串;
返回吨;
}
返回base.ConvertFrom(上下文,文化,价值);
}

公众覆盖对象的ConvertTo(ITypeDescriptorContext背景下,System.Globalization.CultureInfo文化,对象的值,类型destinationType)
{
如果(destinationType == typeof运算(串)及&放大器; value.GetType()== typeof运算(试验))
{
返回((试验)值).TestMember;
}
返回base.ConvertTo(上下文,文化,价值,destinationType);
}

}

[TypeConverterAttribute(typeof运算(TestConverter))]
公共结构测试
{
公共字符串TestMember {搞定;组; }
}
}


解决方案

我有这个问题,以及和解决方法的问题是,手动订阅到当前应用程序域的AssemblyResolve事件,并解决了组装​​。



这是远离很好的解决方案,但它似乎工作。我不知道为什么该框架的行为这种方式。我自己真的想找到解决这个问题的一个不太hackish的方式。

 公共无效DoMagic()
{
//注意:在此之后,您可以使用您的TypeConverter。
AppDomain.CurrentDomain.AssemblyResolve + =新ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

私人大会CurrentDomain_AssemblyResolve(对象发件人,ResolveEventArgs参数)
{
AppDomain中域=(应用程序域)发送;
的foreach(在domain.GetAssemblies大会ASM())
{
如果(asm.FullName == args.Name)
{
返回ASM;
}
}
返回NULL;
}


I am trying to understand why the below code is not working as expected; the TypeDescriptor is simply not picking up the custom converter from the attributes. I can only assume I have made an obvious mistake but I cannot see it.

-- edit -- this code seems to work when I run it in a console on its own, I'm actually calling a converter from within a much more complex application and from a different namespace.

-- edit -- alternatively any suggestions on how I can debug the TypeDescriptor so I can see what is going on and then I can probably answer this myself.

-- edit -- this problem is almost certainly related to pieces being in different assemblies.

-- edit -- It looks like this is not working because of some quirk of loading assemblies dynamically - this code is running under a plugin like architecture.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.ComponentModel;

namespace MyTest
{

    public class TestTester
    {
        public static void Main(string[] args)
        {
            object v = TypeDescriptor.GetConverter(typeof(MyTest.Test)).ConvertFromInvariantString("Test");
        }
    }

    public class TestConverter : TypeConverter
    {

        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return false;
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
        {
            if (sourceType == typeof(string) || base.CanConvertFrom(context, sourceType))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(Test) || base.CanConvertTo(destinationType))
            {
                return true;
            }
            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value.GetType() == typeof(string))
            {
                Test t = new Test();
                t.TestMember = value as string;
                return t;
            }
            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string) && value.GetType() == typeof(Test))
            {
                return ((Test)value).TestMember;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

    }

    [TypeConverterAttribute(typeof(TestConverter))]
    public struct Test
    {
        public string TestMember { get; set; }
    }
}

解决方案

I had this problem as well and a workaround to the problem is to subscribe to the AssemblyResolve event of the current application domain and resolve the assembly manually.

This is far from a good solution, but it seems to work. I have no idea why the framework behaves this way. I would myself really want to find a less hackish way of resolving this problem.

public void DoMagic()
{
    // NOTE: After this, you can use your typeconverter.
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    AppDomain domain = (AppDomain)sender;
    foreach (Assembly asm in domain.GetAssemblies())
    {
        if (asm.FullName == args.Name)
        {
            return asm;
        }
    }
    return null;
}

这篇关于为什么不工作这个类型转换器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆