【问题标题】:Getting Nested Types from Higher in Hierarchy in C#在 C# 中从更高层次中获取嵌套类型
【发布时间】:2016-05-29 20:24:17
【问题描述】:

我有几个名为SortMethod 的类继承自一个名为ASortMethod 的抽象类。这些类中的每一个都嵌套在另一个类中。现在,我正在处理名为CitationCollection 的类中的SortMethod

我正在处理另一个名为CustomSortDictionary 的类。这必须处理给定的SortMethod 类型,但不知道会给出哪个SortMethod 类型,所以我将变量Type sortMethod 存储在CustomSortDictionary 中。

这意味着不幸的是,我不得不处理大量凌乱的反思。在给定的Type sortMethod 中,我希望访问两个主要内容。第一个我可以使用下面的代码访问,但第二个我无法访问。

BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;

// Accessing the first
MethodInfo m = SortMethod.GetMethod("ConstructCustomSortMethods", bindingFlags);
m.Invoke(null, null);

// Accessing the second
IDCollection customSort = (IDCollection)SortMethod.GetNestedType("CustomSort", bindingFlags).GetField("Methods").GetValue(null);

我尝试了BindingFlags 的几种不同组合来尝试获取第二段代码中的嵌套类型,但我无法访问它。我认为问题在于SortMethod.CustomSort.Methods 是在ASortMethod 中声明的,这比CitationCollection.SortMethod 更上一层楼。

如何使用反射正确访问第二项?

完整代码见this link

更新:

我从微软的网站上找到了this,这可能解释了我的问题:

BindingFlags.FlattenHierarchy
指定应返回层次结构上的公共和受保护静态成员。不返回继承类中的私有静态成员。静态成员包括字段、方法、事件和属性。 不返回嵌套类型。

【问题讨论】:

  • 你能提供一个可调试的例子吗?
  • @thehennyy 你的意思是一种方法?这需要很多课程才能拼出,sn-ps 或不。
  • 我认为你在某个地方有这些类,所以你可以去掉所有不需要的东西,只剩下相关的部分。
  • @thehennyy 以下是我在调试时观察到的情况: 1) CitationCollection.SortMethod.CustomSort.Methods 存在; 2) (IDCollection)SortMethod.GetNestedType("CustomSort", bindingFlags).GetField("Methods").GetValue(null) 没有。如果您需要任何其他详细信息或想要完整的代码,请告诉我。
  • @thehennyy 在这里。 pastebin.com/5ShQqcFr

标签: c# reflection types nested hierarchy


【解决方案1】:

你的排序方法type看起来是这样的吧?

public enum SortType { Ascend, Descend, FlyingTriangle }

您可能希望使用一个接口,以便所有实现它的方法都必须接受或拒绝请求的排序。

示例

public interface ISortable
{
    public bool IsValidContext(object record, SortType type);
}

public class SortAlpha : ISortable
{
    public bool IsValidContext(object record, SortType type)
    {
        return type == SortType.Ascend ? true : false; // example
    }
}

public class SortBeta : ISortable
{

    public bool IsValidContext(object record, SortType type)
    {
        return type == SortType.Descend && record is HtmlDocument; // example
    }
}

您可以让方法遍历实现接口的类以查找并返回正确的方法。

【讨论】:

  • 我不太清楚你的意思。 SortMethod 看起来不像。请参阅this link 以获取更大的原始代码 sn-ps。对于界面会提供什么帮助,我也有些困惑。我使用抽象类是出于我认为类似的原因。
  • 另外需要注意的是SortMethod 不是enum。它是一个密封类,以类似于 enum 工作方式的方式存储 ID 对象,但在能够容纳方法、嵌套类型、其他对象等方面更加灵活。
  • 是的,您似乎出于同样的原因使用 Abstract 类。接口只要求实现它的每个类都具有某些成员,因此不需要嵌套。看起来您可以将代码缩短为一个 Sorter 类。只需添加各种方法来处理不同的排序样式。然后使用它看起来像:Sorter sorter = new Sorter(data); 然后YourType sorted = sorter.Sort(someEnumType);
  • 我希望!不幸的是,它在结构方面有点复杂......我同意我们出于同样的原因使用它,但我无法避免嵌套,因为除了 @987654333 之外,我将需要其他类中的 SortMethod 类@。另外,我使用CustomSortDictionary 来存储这些方法,以便可以通过编程方式添加它们而无需实际停止程序并编辑源代码,因为这不切实际。这使未来更容易。您在 Pastebin 的代码中看到的 IDs 用于识别方法。
  • 然后,IDCollection CitationCollection.SortMethod.CustomSort.Methods 用于存储与IDs 相关的名称,尽管这听起来有点荒谬。我这样做只是为了让我觉得我正在处理带有名称的字段,就像 SortMethod.Bibliography 或其兄弟姐妹一样。
【解决方案2】:

由于CustomSort 类型总是嵌套在ASortMethod 中,您可以直接获取它:

((IDCollection)typeof(ASortMethod.CustomSort).GetField("Methods").GetValue(null)).Add(ref name);

当您由于某种原因无法找到时,您可以向上遍历基本类型,直到到达 object 以找到 CustomSort 的封闭类型

((IDCollection)FindBase(SortMethod).GetNestedType("CustomSort", bindingFlags).GetField("Methods").GetValue(null)).Add(ref name);

static Type FindBase(Type t)
{
    if (t.BaseType != typeof (object))
        return FindBase(t.BaseType);

    return t;
}

【讨论】:

  • 使用ASortMethod 的唯一问题是每个SortMethod 类型将有一个不同的CustomSort.Methods 对象。除非我对从抽象类继承的静态字段有什么误解......你能澄清我的误解吗?否则,看起来不错。递归爬升很聪明。
  • @Jenguinie 老实说,在这种情况下我不确定,但由于字段是静态的,所以总是只有一个字段。
  • Welp,我想只有一种方法可以找出答案...我将对其进行测试,看看更改其中一个的值是否会更改另一个的值。
  • 不幸的是,两者是一回事。
  • 这整个结构有问题,那么……我最终不得不把它变成一个界面,很有可能。
猜你喜欢
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2018-06-04
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多