【问题标题】:How can I get System.Type from "System.Drawing.Color" string如何从“System.Drawing.Color”字符串中获取 System.Type
【发布时间】:2009-06-03 12:43:08
【问题描述】:

我有一些控件的 xml 存储属性

<Prop Name="ForeColor" Type="System.Drawing.Color" Value="-16777216" />

我想把它转换成其他人

System.Type type = System.Type.GetType(propertyTypeString);
object propertyObj = 
  TypeDescriptor.GetConverter(type).ConvertFromString(propertyValueString);

System.Type.GetType("System.Drawing.Color") 返回 null。

问题是如何正确地从字符串中获取颜色类型

(最好不要只为颜色属性做特殊情况)

更新

有时会手动编辑此 xml

【问题讨论】:

  • 更改不会触及颜色本身(以防万一您此时在 Value 属性上加注)

标签: c# .net reflection .net-2.0


【解决方案1】:

使用Type.GetType()时需要指定程序集以及类型名称,除非类型在mscorlib或当前正在执行的程序集中。

如果您知道它在 System.Drawing 程序集中,则可以改用 Assembly.GetType() - 或者查看可能的程序集的完整列表:

Type type = candidateAssemblies.Select(assembly => assembly.GetType(typeName))
                               .Where(type => type != null)
                               .FirstOrDefault();

if (type != null)
{
    // Use it
}
else
{
    // Couldn't find the right type
}

【讨论】:

  • AFAIK,GetType 方法抛出了很多......即使你提供参数 (throwOnErrors=false) 他们仍然抛出 (arrrrgh),所以你需要保护 Select 的内部 lambda,它使其可读性和清晰度降低等。
  • Assembly.GetType 仅在它非常非常糟糕的情况下抛出 - 如果它找到类型名称,但依赖关系已损坏,或者类型名称本身无效或为空。特别是,它不会仅仅因为程序集不包含该类型而引发。我认为这可能是理想的行为。
【解决方案2】:

您是否已加载 System.Drawing 程序集?你有参考吗?

【讨论】:

  • 是的。我对它有一个引用,当我到达该行时,我可以看到它已加载。
【解决方案3】:

您自己是否将这些属性存储在 XML 中?如果是这样,只需在创建节点时编写对象的 AssemblyQualifiedName 而不是 FullName。这给出了使用Type.GetType()从字符串加载类型所需的程序集上下文信息

【讨论】:

  • +1 好电话。如果这是一个选项,它比搜索多个程序集要好。
  • 在可预测性方面更好 - 但在可读性方面更差,特别是如果它是带有版本字符串等的签名程序集。
  • 也许,在 System.Drawing 的情况下这不是问题,但如果您将 QualifiedName 用于某些自定义程序集,当这些程序集升级到另一个版本时,您可能会遇到问题。
  • @Jon:我不确定我是否同意可读性方面。可读性实际上应该只被视为用户在查看 XML 时是否能分辨出类型是什么。 “垃圾”(版本字符串、PK 等)都在最后。类型和程序集名称以非常易读的格式放在前面。对于这样的事情,我希望最终用户的可变性不会成为问题,因为希望用户不会手动编辑这类信息。
  • @Yacoder:您还可以提出假设跨程序集版本的兼容性(特别是如果它们不在您的控制范围内)可能会导致同样多的问题。不过,我相当肯定(但我可能是错的),除非程序集是强签名的,否则即使版本不匹配,活页夹也会使用另一个同名的程序集,所以不是强签名应该使它仍然工作。
【解决方案4】:

也许这与您的问题不完全相关,但我有一个类似的问题。我需要使用XmlSerializer 序列化/反序列化颜色。在网上搜索并结合几位作者的智慧后,我想出了包装类:

/// <summary>
/// Color that can be xml-serialized
/// </summary>
public class SerializableColor
{
    public int A { get; set; }
    public int R { get; set; }
    public int G { get; set; }
    public int B { get; set; }
    public int KnownColor { get; set; }

    /// <summary>
    /// Intended for xml serialization purposes only
    /// </summary>
    private SerializableColor() { }

    public SerializableColor(Color color)
    {
        this.A = color.A;
        this.R = color.R;
        this.G = color.G;
        this.B = color.B;
        this.KnownColor = (int)color.ToKnownColor();
    }

    public static SerializableColor FromColor(Color color)
    {
        return new SerializableColor(color);
    }

    public Color ToColor()
    {
        if (KnownColor != 0)
        {
            return Color.FromKnownColor((KnownColor)KnownColor);
        }
        else
        {
            return Color.FromArgb(A, R, G, B);
        }
    }
}

也许它可以应用于您的情况。 您会看到,Color 类有时不会将自身存储为 ARGB 值的组合,而是存储为 KnownColor 枚举值...在序列化过程中需要保留。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2010-12-27
    • 2021-04-15
    • 2011-11-30
    • 2017-07-28
    • 2012-07-23
    相关资源
    最近更新 更多