gpt4 book ai didi

c# - TargetInvocationException @ PropertyInfo.GetValue(target, null) 与目标类型 MemoryStream

转载 作者:太空宇宙 更新时间:2023-11-03 23:28:24 28 4
gpt4 key购买 nike

我想读取对象的所有公共(public)属性值并编写了以下代码:

private List<PropertyInfo> GetListOfProperties(object objectToRegister,
BindingFlags bindingFlags = BindingFlags.Instance |
BindingFlags.Public)
{
Type type = objectToRegister.GetType();
List<PropertyInfo> curListOfProperties = new List<PropertyInfo>();
curListOfProperties.AddRange(type.GetProperties()
.Where((propertyInfo) =>
!propertyInfo.GetIndexParameters().Any()));
return curListOfProperties;
}

然后这样调用它:

var objectToRegister = new MemoryStream();

// ... eventually write things into MemoryStream e.g. Image.Save(objectToRegister , "Bmp")
// ... eventually do nothing with objectToRegister

foreach (var propertyInfo in GetListOfProperties(objectToRegister))
{
if (propertyInfo.CanRead)
{
// -->> TargetInvocationException
value = propertyInfo.GetValue(objectToRegister , null);
}
}

异常看起来像这样

System.InvalidOperationException: Timeouts are not supported on this stream. at System.IO.Stream.get_ReadTimeout()

现在我想从 GetListOfProperties 的返回值中排除这些不受支持的属性

最佳答案

我觉得你的代码本身没问题。

但我怀疑您的方法存在一个基本的设计缺陷:即您假设您可以随时随地以任何顺序成功读取任何属性。

精心设计的类型可能会满足这个假设,但不幸的是,有些类型遵循不同的协议(protocol):

  • 一个对象可能有一个属性 HasValue,它指定是否可以查询另一个属性 Value(或者这是否会导致 InvalidOperationException 或类似的)。

    (设计更好的类型可能有 TryGetValue 方法或可为空的 Value 属性。)

  • 一个对象可能必须先被初始化-d,然后才能对其进行任何操作。

等您在 Stream.ReadTimeout 中遇到了另一个这样的例子,显然 MemoryStream 不支持它。

如果你必须让你的反射代码与任何类型一起工作,这里有一些选项:

  1. 最简单的方法是通过将对 propertyInfo.GetValue 的调用包装在 try/catch 中来简单地“忽略”任何错误> block (并可能将所有捕获的异常收集到 AggregateException 中)。

  2. 如果您想以不同的方式对待某些特定类型以解决特定问题(例如您使用 MemoryStream 的情况),您可以创建反射代码的各种实现并根据以下内容选择策略对象的 Type。这是一个非常粗略的例子,可以给你一个想法:

    interface IPropertyInspector
    {
    PropertyInfo[] GetProperties(object obj);
    }

    class GenericPropertyInspector : IPropertyInspector { /* your current implementation */ }

    class StreamPropertyInspector : IPropertyInspector { /* does not return e.g. ReadTimeout if CanTimeout is false */ }

    Dictionary<Type, IPropertyInspector> inspectors = ...;
    inspectors[typeof(MemoryStream)] = new StreamPropertyInspector();

    ...
    Type t = objectToRegister.GetType();
    IPropertyInspector inspector;
    if (!inspectors.TryGetValue(t, out inspector))
    {
    inspector = new GenericPropertyInspector();
    }
    var properties = inspector.GetProperties(objectToRegister):
    // do something with properties

    这种额外的间接级别将允许您过滤掉已知会导致问题的属性。

关于c# - TargetInvocationException @ PropertyInfo.GetValue(target, null) 与目标类型 MemoryStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33066378/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com