Ищете более динамичную сериализацию конструктора TypeConverter в форме VS10 .NET

#c# #visual-studio #visual-studio-2010 #serialization #design-time

#c# #visual-studio #visual-studio-2010 #сериализация #время разработки

Вопрос:

У меня есть список класса, который я сериализую в сгенерированный дизайнером код со следующим кодом:

 internal class TargetSettingsConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(InstanceDescriptor) amp;amp; value is ControlListManager.TargetSettings)
        {
            ConstructorInfo constructor = typeof(ControlListManager.TargetSettings).GetConstructor(new[] { typeof(object), typeof(string), typeof(DisplayModes), typeof(bool), typeof(int), typeof(int), typeof(int) });
            var target = value as ControlListManager.TargetSettings;
            var descriptor = new InstanceDescriptor(constructor, new[] { target.Target, target.Text, target.DisplayMode, target.Fade, target.HideTimeout, target.PaddingX, target.PaddingY }, true);
            return descriptor;
        }
        if (culture == null) { culture = CultureInfo.CurrentCulture; }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}
  

Пока это работает хорошо, но меня беспокоит то, что я должен указывать типы и значения по отдельности.

Моей первой идеей было использовать getConstructor s() вместо этого. Но тогда проблема значений все еще остается. Я действительно смущен этой проблемой, поскольку я на самом деле пишу функцию, не зная количества параметров — или только если она «жестко запрограммирована».

У кого-нибудь есть идеи, как это можно сделать лучше?

Редактировать: класс данных

     [TypeConverter(typeof(TargetSettingsConverter))]
    public class TargetSettings : IEquatable<TargetSettings>
    {
        public object Target = new { };
        public string Text;
        public DisplayModes DisplayMode = DisplayModes.FollowXY;
        public bool Fade = true;
        public int HideTimeout;
        public int PaddingX;
        public int PaddingY;
        public bool Equals(TargetSettings other)
        {
            return other != null amp;amp; (Target.Equals(other.Target));
        }
        public override bool Equals(object obj)
        {
            if (obj == null) { return false; }
            TargetSettings objAsPart = obj as TargetSettings;
            if (objAsPart == null) { return false; }
            return Equals(objAsPart);
        }
        public override int GetHashCode()
        {
            return Target.GetHashCode();
        }
        public TargetSettings(object target, string text = "", DisplayModes displayMode = DisplayModes.FollowXY, bool fade = true, int hideTimeout = 0, int paddingX = 0, int paddingY = 0)
        {
            Target = target;
            Text = text;
            DisplayMode = displayMode;
            Fade = fade;
            HideTimeout = hideTimeout;
            PaddingX = paddingX;
            PaddingY = paddingY;
        }
    }
  

Комментарии:

1. основываясь на моем тесте, я не могу найти класс ControlListManager. Целевые настройки. Это класс, который вы создали сами? Если да, пожалуйста, предоставьте его.

2. Конечно, я обновлю свой вопрос.

Ответ №1:

Исходя из вашего вопроса, вы хотите сделать свой код более динамичным для типов и значений.

Поскольку типы и значения, которые вы хотите преобразовать, относятся ко всем типам полей. Я рекомендую вам использовать отражение для этого.

Вы можете получить все типы полей следующим образом:

  Type []tarr = typeof(TargetSettings).GetFields().Select(i => i.FieldType).ToArray();
 ConstructorInfo constructor = typeof(TargetSettings).GetConstructor(tarr);
  

Вы можете получить все значения полей следующим образом:

 object []oarr= typeof(TargetSettings).GetFields().Select(i => i.GetValue(target)).ToArray();
var descriptor = new InstanceDescriptor(constructor, oarr, true);
  

Полный код:

 internal class TargetSettingsConverter : TypeConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(InstanceDescriptor) amp;amp; value is TargetSettings)
            {
                Type []tarr = typeof(TargetSettings).GetFields().Select(i => i.FieldType).ToArray();
                ConstructorInfo constructor = typeof(TargetSettings).GetConstructor(tarr);
                var target = value as TargetSettings;
                object []oarr= typeof(TargetSettings).GetFields().Select(i => i.GetValue(target)).ToArray();
                var descriptor = new InstanceDescriptor(constructor, oarr, true);
                return descriptor;
            }
            if (culture == null) { culture = CultureInfo.CurrentCulture; }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }


    [TypeConverter(typeof(TargetSettingsConverter))]
    public class TargetSettings : IEquatable<TargetSettings>
    {
        public object Target = new { };
        public string Text;
        public DisplayModes DisplayMode = DisplayModes.FollowXY;
        public bool Fade = true;
        public int HideTimeout;
        public int PaddingX;
        public int PaddingY;
        public bool Equals(TargetSettings other)
        {
            return other != null amp;amp; (Target.Equals(other.Target));
        }
        public override bool Equals(object obj)
        {
            if (obj == null) { return false; }
            TargetSettings objAsPart = obj as TargetSettings;
            if (objAsPart == null) { return false; }
            return Equals(objAsPart);
        }
        public override int GetHashCode()
        {
            return Target.GetHashCode();
        }
        public TargetSettings(object target, string text = "", DisplayModes displayMode = DisplayModes.FollowXY, bool fade = true, int hideTimeout = 0, int paddingX = 0, int paddingY = 0)
        {
            Target = target;
            Text = text;
            DisplayMode = displayMode;
            Fade = fade;
            HideTimeout = hideTimeout;
            PaddingX = paddingX;
            PaddingY = paddingY;
        }
    }

    public enum DisplayModes
    {
        FollowXY

    }