本文整理汇总了C#中IronRuby.Builtins.RubyClass.ForEachAncestor方法的典型用法代码示例。如果您正苦于以下问题:C# RubyClass.ForEachAncestor方法的具体用法?C# RubyClass.ForEachAncestor怎么用?C# RubyClass.ForEachAncestor使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IronRuby.Builtins.RubyClass
的用法示例。
在下文中一共展示了RubyClass.ForEachAncestor方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: TryGetClrMethod
/// <summary>
/// There are basically 4 cases:
/// 1) CLR method of the given name is not defined in the specified type.
/// Do nothing, the method will be found as we traverse the hierarhy towards the Kernel module.
/// 2) Otherwise
/// 1) There is no RubyMemberInfo of given <c>name</c> present in the (type..Kernel] ancestors.
/// We need to search all types in (type..Object] for CLR method overloads.
/// 2) There is a RubyMemberInfo in a class, say C, in (type..Kernel].
/// We need to get CLR methods from (type..C) in addition to the members in the type.
/// 1) C.HidesInheritedOverloads == true
/// All overloads of the method we look for are in [type..C).
/// 2) C.HidesInheritedOverloads == false
/// All overloads of the method we look for are in [type..C) and in the RubyMemberInfo.
/// </summary>
internal bool TryGetClrMethod(RubyClass/*!*/ cls, Type/*!*/ type, BindingFlags bindingFlags, string/*!*/ name, string/*!*/ clrName, out RubyMemberInfo method) {
// declared only:
MemberInfo[] initialMembers = GetDeclaredClrMethods(type, bindingFlags, clrName);
int initialVisibleMemberCount = GetVisibleMethodCount(initialMembers);
if (initialVisibleMemberCount == 0) {
// case [1]
method = null;
return false;
}
// inherited overloads:
List<RubyClass> ancestors = new List<RubyClass>();
RubyMemberInfo inheritedRubyMember = null;
bool skipHidden = false;
cls.ForEachAncestor((module) => {
if (module != cls) {
if (module.TryGetDefinedMethod(name, ref skipHidden, out inheritedRubyMember) && !inheritedRubyMember.IsSuperForwarder) {
return true;
}
// Skip classes that have no tracker, e.g. Fixnum(tracker) <: Integer(null) <: Numeric(null) <: Object(tracker).
// Skip interfaces, their methods are not callable => do not include them into a method group.
// Skip all classes once hidden sentinel is encountered (no CLR overloads are visible since then).
if (!skipHidden && module.TypeTracker != null && module.IsClass) {
ancestors.Add((RubyClass)module);
}
}
// continue:
return false;
});
_allMethods = null;
if (inheritedRubyMember != null) {
// case [2.2.2]: add CLR methods from the Ruby member:
var inheritedGroup = inheritedRubyMember as RubyMethodGroupInfo;
if (inheritedGroup != null) {
AddMethodsOverwriteExisting(inheritedGroup.MethodBases, inheritedGroup.OverloadOwners);
}
}
// populate classes in (type..Kernel] or (type..C) with method groups:
for (int i = ancestors.Count - 1; i >= 0; i--) {
var declared = GetDeclaredClrMethods(ancestors[i].TypeTracker.Type, bindingFlags, clrName);
if (declared.Length != 0 && AddMethodsOverwriteExisting(declared, null)) {
// There is no cached method that needs to be invalidated.
//
// Proof:
// Suppose the group being created here overridden an existing method that is cached in a dynamic site invoked on some target class.
// Then either the target class is above all ancestors[i] or below some. If it is above then the new group doesn't
// invalidate validity of the site. If it is below then the method resolution for the cached method would create
// and store to method tables all method groups in between the target class and the owner of the cached method, including the
// one that contain overloads of ancestors[i]. But no module below inheritedRubyMember contains a method group of the name
// being currently resolved.
ancestors[i].AddMethodNoCacheInvalidation(name, MakeAllMethodsGroup(ancestors[i]));
}
}
if (_allMethods != null) {
// add members declared in self:
AddMethodsOverwriteExisting(initialMembers, null);
// return the group, it will be stored in the method table by the caller:
method = MakeAllMethodsGroup(cls);
} else {
method = MakeSingleOwnerGroup(cls, initialMembers, initialVisibleMemberCount);
}
return true;
}
示例2: IsMethodVisible
private bool IsMethodVisible(RubyMemberInfo/*!*/ method, RubyModule/*!*/ owner, RubyClass visibilityContext, bool foundCallerSelf) {
// call with implicit self => all methods are visible
if (visibilityContext == RubyClass.IgnoreVisibility) {
return true;
}
if (method.Visibility == RubyMethodVisibility.Protected) {
// A protected method is visible if the caller's self immediate class is a descendant of the method owner.
if (foundCallerSelf) {
return true;
}
// walk ancestors from caller's self class (visibilityContext)
// until the method owner is found or this module is found (this module is a descendant of the owner):
return visibilityContext.ForEachAncestor((module) => module == owner || module == this);
}
return method.Visibility == RubyMethodVisibility.Public;
}