Вы можете использовать шифрование байтового кода без страха.
Дело в том, что цитируемый выше документ «Cracking Java byte-code encryption» содержит логическую ошибку. Основная претензия к статье перед запуском всех классов должна быть расшифрована и передана методу ClassLoader.defineClass(...)
. Но это не так.
Предполагаемое здесь недопустимое значение - при условии, что они работают в аутентичной или стандартной среде java run-time . Ничто не может заставить защищенное Java-приложение не только запускать эти классы, но даже расшифровывать и передавать их на ClassLoader
. Другими словами, если вы находитесь в стандартной JRE, вы не можете перехватить метод defineClass(...)
, потому что стандартная java не имеет API для этой цели, и если вы используете модифицированную JRE с исправленным ClassLoader
или любым другим «хакерским трюком», вы можете 't делать это, потому что защищенное приложение Java не будет работать вообще, и поэтому вам нечего перехватывать. И совершенно неважно, какой «патч-искатель» используется или какой трюк используется хакерами. Эти технические детали - совсем другая история.
Оператор нулевого распространения возвращает значение. И поскольку у вас должна быть переменная с левой стороны задания, а не значение, вы не можете использовать ее таким образом.
Конечно, вы могли бы сделать вещи короче, используя оператор tenary, но что, с другой стороны, не очень помогает аспекту читаемости.
Комментарий Иоахима Исакссона по вашему вопросу показывает другой подход, который должен работать.
Общий метод расширения SetValue (но только для свойств ref) будет:
public static void SetValue<T>(this T property, T value)
{
property = value;
}
И будет использоваться как
ButtonOrNull?.Visibility.SetValue(Visibility.Hidden);
T property
должен был быть параметром ref для изменения, потому что единственное, что вы делаете, это установить локальную копию свойства внутри функции, и вы не можете this ref
, и C # не разрешает доступ к свойствам (в отличие от VB, что на самом деле является настоящим позором).
– Mike Marynowski
29 September 2017 в 15:35
Как предложил Йохахим Исакссон в комментариях, теперь у меня есть метод SetData(Data data)
и используйте его следующим образом:
MyPage1?.SetData(this.data);
MyPage2?.SetData(this.data);
MyPage3?.SetData(this.data);
Я придумал следующее расширение:
public static class ObjectExtensions
{
public static void SetValue<TValue>(this object @object, string propertyName, TValue value)
{
var property = @object.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (property?.CanWrite == true)
property.SetValue(@object, value, null);
}
}
, которое можно назвать глобально; это работает только в публичных свойствах.
myObject?.SetValue("MyProperty", new SomeObject());
Следующая улучшенная версия работает на что угодно,
public static void SetValue<TObject>(this TObject @object, Action<TObject> assignment)
{
assignment(@object);
}
И также может быть вызвана глобально,
myObject?.SetValue(i => i.MyProperty = new SomeObject());
Но имя расширения несколько вводит в заблуждение, поскольку Action
не требует исключительно назначения.
Попробуйте добавить все ваши страницы в myPageList.
IEnumerable<MyPage> myPageList;
foreach(MyPage myPage in myPageList)
{
if (myPage != null)
myPage.Data = this.data;
}