Обязательно используйте последнюю версию в файле build.gradle
:
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
И определите ConstraintLayout
в файлах XML как:
<androidx.constraintlayout.widget.ConstraintLayout
...
/>
К сожалению, Android Jetpack инструмент работает не так хорошо, как следовало бы, и вам придется изменить код вручную.
Мы должны будем иметь дело с точки зрения методов свойства здесь, а не самого свойства, потому что это - получение/методы установки свойства, которое на самом деле переопределяется, а не само свойство. Я буду использовать получить метод, поскольку у Вас никогда не должно быть свойства без одного, хотя полное решение должно проверить из-за отсутствия одного.
Смотря на IL, испускаемый во многих случаях, 'получить' метод основного свойства будет иметь маркеры метаданных (это из компилятора C#; другие не могут испустить hidebysig
в зависимости от их метода, скрывающего семантику, в этом случае, метод был бы скрытием по имени):
non-virtual : .method public hidebysig specialname instance
virtual : .method public hidebysig specialname newslot virtual instance
Полученный будет иметь следующие маркеры:
override : .method public hidebysig specialname virtual instance
new : .method public hidebysig specialname instance
new virtual : .method public hidebysig specialname newslot virtual instance
Таким образом, мы видим от этого, что не возможно сказать просто от маркеров метаданных метода, является ли это new
потому что невиртуальный базовый метод имеет те же маркеры как невиртуальное new
метод и виртуальный базовый метод имеют те же маркеры как new virtual
метод.
То, что мы можем сказать, является этим, если метод имеет virtual
маркер, но не newslot
маркер затем это переопределяет базовый метод, а не тени это, т.е.
var prop = typeof(ChildClass).GetProperty("TempProperty");
var getMethod = prop.GetGetMethod();
if ((getMethod.Attributes & MethodAttributes.Virtual) != 0 &&
(getMethod.Attributes & MethodAttributes.NewSlot) == 0)
{
// the property's 'get' method is an override
}
Предположение, затем, что мы находим 'получить' метод, не является переопределением, мы хотим знать, существует ли свойство в базовом классе, что это - затенение. Проблема состоит в том, что, потому что метод находится в другом слоте таблицы метода, он на самом деле не имеет никакой непосредственной связи к методу, это - затенение. Таким образом, то, что мы на самом деле говорим, "делает базовый тип, имеют любой метод, который соответствует критериям для затенения", которое варьируется в зависимости от того, является ли метод hidebysig
или скрытие по имени.
Для первого мы должны проверить, имеет ли базовый класс какой-либо метод, который соответствует подписи точно, тогда как для последнего мы должны проверить, имеет ли это любой метод с тем же именем, таким образом продолжая код сверху:
else
{
if (getMethod.IsHideBySig)
{
var flags = getMethod.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
flags |= getMethod.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
var paramTypes = getMethod.GetParameters().Select(p => p.ParameterType).ToArray();
if (getMethod.DeclaringType.BaseType.GetMethod(getMethod.Name, flags, null, paramTypes, null) != null)
{
// the property's 'get' method shadows by signature
}
}
else
{
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
if (getMethod.DeclaringType.BaseType.GetMethods(flags).Any(m => m.Name == getMethod.Name))
{
// the property's 'get' method shadows by name
}
}
}
Я думаю, что это - большая часть пути там, но я все еще не думаю, что это точно правильно. Для запуска я не полностью знаком с сокрытием по имени, поскольку C# не поддерживает его, и это - в значительной степени все, что я использую, таким образом, я могу быть неправым в коде здесь, который указывает, что метод экземпляра мог тень статическая. Я также не знаю о проблеме чувствительности к регистру (например, в VB мог названный метод Foo
тень названный метод foo
если они оба имели ту же подпись и были обоими hidebysig
- в C# ответ не, но если ответ - да в VB затем, это означает, что ответ на этот вопрос на самом деле недетерминирован).
Ну, я не уверен, сколько справки все это, кроме проиллюстрировать, что это - на самом деле намного более трудная проблема, чем я думал, что это будет (или я пропустил что-то действительно очевидное, в этом случае, я хотел бы знать!). Но надо надеяться это имеет достаточное содержание, что это помогает Вам достигнуть того, что Вы пытаетесь сделать.
Я никогда не делал то, что Вы пытаетесь сделать только MethodInfo. GetBaseDefinition () метод, кажется, то, что Вы ищете.
Это возвращает MethodInfo, этот метод является переопределяющим.
Из MSDN:
Если данный метод указан с новым ключевым словом (как в newslot, как описано в участниках Типа), данный метод возвращается.
Не похож на отражение, даст это Вам по умолчанию, таким образом, Вы будете иметь к самокрутке:
public static bool IsHidingMember( this PropertyInfo self )
{
Type baseType = self.DeclaringType.BaseType;
PropertyInfo baseProperty = baseType.GetProperty( self.Name, self.PropertyType );
if ( baseProperty == null )
{
return false;
}
if ( baseProperty.DeclaringType == self.DeclaringType )
{
return false;
}
var baseMethodDefinition = baseProperty.GetGetMethod().GetBaseDefinition();
var thisMethodDefinition = self.GetGetMethod().GetBaseDefinition();
return baseMethodDefinition.DeclaringType != thisMethodDefinition.DeclaringType;
}
Не уверенный, как это будет работать с индексируемыми свойствами, однако!
Исправление при использовании VB свойство, которое Вы ищете, является "IsHideBySig". Это будет ложью в случае, что "новое" ключевое слово использовалось для определения метода/свойства.
В случае C# оба экземпляра производятся как "hidebysig". Спасибо за указание на это Greg. Я не понял, что только протестировал это в VB. Вот демонстрационный код VB, который будет репродукция это поведение.
Module Module1
Class Foo
Public Function SomeFunc() As Integer
Return 42
End Function
End Class
Class Bar
Inherits Foo
Public Shadows Function SomeFunc() As Integer
Return 36
End Function
End Class
Sub Main()
Dim type = GetType(Bar)
Dim func = type.GetMethod("SomeFunc")
Stop
End Sub
End Module