我有一个用DefaultValueAttribute
装饰的财产。
代码如下所示:
[DefaultValue(typeof(Encoding), "utf-8")]
public Encoding Encoding { get; set; }
还有一个重置方法可以恢复所有属性的所有默认值:
public void Reset()
{
foreach (var property in TypeDescriptor.GetProperties(typeof(ILoggedChannelValueFileExportInfo)).Cast<PropertyDescriptor>())
{
property.ResetValue(this);
}
}
这适用于所有标准属性,包括具有ReturnType CultureInfo
的属性。
我尝试指定utf-8
,utf8
,两者都是大写,但没有任何作用。
我需要指定什么才能使其正常工作?
我能通过反思来做到这一点,但我希望有一种方法可以使用TypeDescriptor
。
编辑:
由于Hans Passant的回答,我写了TypeConverter
。这就是整个代码:
public class Foo
{
[TypeConverter(typeof(EncodingTypeConverter))]
[DefaultValue(typeof(Encoding), "UTF-8")]
public Encoding Encoding { get; set; }
public void Reset()
{
foreach (var property in TypeDescriptor.GetProperties(this).Cast<PropertyDescriptor>())
{
property.ResetValue(this);
}
}
}
public class EncodingTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return value is string ? Encoding.GetEncoding((string)value) : base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
return destinationType == typeof(string) ? value.ToString() : base.ConvertTo(context, culture, value, destinationType);
}
}
创建实例并调用Reset
编码仍为空,并且不会从EncodingTypeConverter
调用任何方法。我该怎么办?“
没有涉及UI - 没有属性网格。唯一的是TypeDescriptor应该重置值。
编辑:
编写自己的TypeConverter
- 调用几乎是不可能的,因为DefaultValueAttribute
不会存储指定的字符串值。好痛。这是我的实施,但不起作用。也许有人可以用它来创建解决方案:
public virtual void ResetValues()
{
foreach (var property in TypeDescriptor.GetProperties(typeof(TAttributedType)).Cast<PropertyDescriptor>())
{
if (property.CanResetValue(this))
{
property.ResetValue(this);
continue;
}
var defaultValueAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];
var typeConverterAttribute = (TypeConverterAttribute)property.Attributes[typeof(TypeConverterAttribute)];
if (defaultValueAttribute == null || !(defaultValueAttribute.Value is string) ||
typeConverterAttribute == null || string.IsNullOrWhiteSpace(typeConverterAttribute.ConverterTypeName))
{
continue;
}
var typeConverterType = Type.GetType(typeConverterAttribute.ConverterTypeName);
if (typeConverterType == null)
{
continue;
}
var typeConverter = (TypeConverter)Activator.CreateInstance(typeConverterType);
if (typeConverter.CanConvertFrom(typeof(string)))
{
var propertyValue = typeConverter.ConvertFrom(defaultValueAttribute.Value);
if (propertyValue != null)
{
property.SetValue(this, propertyValue);
}
}
}
}
答案 0 :(得分:0)
添加TypeConverterAttribute
并定义DefaultValue(typeof(Encoding), "UTF-8")
将无效。 DefaultValue
的构造函数尝试从不使用TypeConverter
的{{1}}中找到TypeDescriptor
。
以下是TypeConverterAttribute
- 方法的实现,该方法使用ResetValues
中的字符串值和DefaultValueAttribute
来加载默认值。
TypeConverterAttribute
使用过的public virtual void ResetValues()
{
foreach (var property in TypeDescriptor.GetProperties(typeof(TAttributedType)).Cast<PropertyDescriptor>())
{
var defaultValueAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];
var typeConverterAttribute = (TypeConverterAttribute)property.Attributes[typeof(TypeConverterAttribute)];
if (defaultValueAttribute != null && defaultValueAttribute.Value is string &&
typeConverterAttribute != null && !string.IsNullOrWhiteSpace(typeConverterAttribute.ConverterTypeName))
{
var typeConverterType = Type.GetType(typeConverterAttribute.ConverterTypeName);
if (typeConverterType != null)
{
var typeConverter = (TypeConverter)Activator.CreateInstance(typeConverterType);
if (typeConverter.CanConvertFrom(typeof(string)))
{
var propertyValue = typeConverter.ConvertFrom(defaultValueAttribute.Value);
if (propertyValue != null)
{
property.SetValue(this, propertyValue);
continue;
}
}
}
}
if (property.CanResetValue(this))
{
property.ResetValue(this);
}
}
}
是:
TypeConverter
attibuted属性是:
public class EncodingTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return value is string ? Encoding.GetEncoding((string)value) : base.ConvertFrom(context, culture, value);
}
}
请注意,[TypeConverter(typeof(EncodingTypeConverter))]
[DefaultValue("UTF-8")]
public Encoding Encoding { get; set; }
- 方法首先测试ResetValues
和指定的TypeConverter
。这是必需的,因为如果将字符串指定为默认值,DefaultValue
将返回PropertyDescriptor.CanResetValue()
。这不能转换为编码。