将值类型数组转换为引用类型数组
Converting value type array to reference type array
我需要编写一个异常 class 来接受消息和任何类型的信息对象(通常是匿名对象)。
我有以下代码:
public SpecialException(string message, object info) : this(message)
{
StringBuilder sb = new StringBuilder();
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(info.GetType()))
{
object value = property.GetValue(info);
string valueStr = value.GetType().IsArray ? (value as IEnumerable<object>).Select(x => x.ToString()).Aggregate((x, y) => $"{x}, {y}") : value.ToString();
sb.AppendLine($"{property.Name} = {valueStr}");
}
Info = sb.ToString();
}
问题是,当匿名对象的属性之一是值类型项的数组时,此代码不起作用,因为它们不继承对象并且这种类型的协方差无法与它们一起使用。
我尝试过但发现不起作用或不够优雅的方法:
- 使用
Dictionary<string, object>
- 无法覆盖 Add
方法
- 使用
IDictionary<string, object>
接口 - 不想为一个简单的异常实现接口的所有方法
- 使用
ExpandoObject
和 dynamic
关键字 - 运行 会遇到与上述代码相同的问题
- 使用
dynamic
和 Newtonsoft JSON 序列化为 JSON - 不想依赖第三方库(或 Web DLL)
我假设有一种优雅的方式(可能使用反射)来实现这一点,也许是通过某种方式遍历数组。谁能提出解决方案?
Variance 不适用于值类型。因此,值类型数组不能转换为 IEnumerable<object>
,但它仍然可以转换为非泛型 IEnumerable
接口。之后你可以调用 Cast<object>()
扩展方法来获取 IEnumerable<object>
实例。
((IEnumerable)value).Cast<object>()
我需要编写一个异常 class 来接受消息和任何类型的信息对象(通常是匿名对象)。
我有以下代码:
public SpecialException(string message, object info) : this(message)
{
StringBuilder sb = new StringBuilder();
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(info.GetType()))
{
object value = property.GetValue(info);
string valueStr = value.GetType().IsArray ? (value as IEnumerable<object>).Select(x => x.ToString()).Aggregate((x, y) => $"{x}, {y}") : value.ToString();
sb.AppendLine($"{property.Name} = {valueStr}");
}
Info = sb.ToString();
}
问题是,当匿名对象的属性之一是值类型项的数组时,此代码不起作用,因为它们不继承对象并且这种类型的协方差无法与它们一起使用。
我尝试过但发现不起作用或不够优雅的方法:
- 使用
Dictionary<string, object>
- 无法覆盖Add
方法 - 使用
IDictionary<string, object>
接口 - 不想为一个简单的异常实现接口的所有方法 - 使用
ExpandoObject
和dynamic
关键字 - 运行 会遇到与上述代码相同的问题 - 使用
dynamic
和 Newtonsoft JSON 序列化为 JSON - 不想依赖第三方库(或 Web DLL)
我假设有一种优雅的方式(可能使用反射)来实现这一点,也许是通过某种方式遍历数组。谁能提出解决方案?
Variance 不适用于值类型。因此,值类型数组不能转换为 IEnumerable<object>
,但它仍然可以转换为非泛型 IEnumerable
接口。之后你可以调用 Cast<object>()
扩展方法来获取 IEnumerable<object>
实例。
((IEnumerable)value).Cast<object>()