Альтернатива перегрузке оператора присваивания - C#

Узнай цену своей работы

Формулировка задачи:

Я знаю, что перегрузка оператора присваивания в C# не возможна. Мне нужно найти альтернативный способ для решения следующей задачи, которая бы легко решалось, если бы перегрузка оператора присваивания была возможна.

В нижеприведенном коде я создаю структуру ObscuredInt, которая предназначена для скрытия от просмотрщиков памяти используемого в ней int-значения с помощью симметричного шифрования. Мне необходимо видоизменить этот код таким образом, чтобы в нем появилась возможность вызова метода RandomizeCryptoKey() ПЕРЕД осуществлением операции присваивания для переменных с типом структуры ObscuredInt. Сейчас мне каждый раз в основном коде тестовой программы приходится вручную вызывать метод RandomizeCryptoKey() на каждом экземпляре переменной типа ObscuredInt.

Подскажите, как нужно видоизменить код для структуры ObscuredInt, чтобы метод RandomizeCryptoKey() вызывался в ней каждый раз перед выполнением операции присваивания для переменной этого типа?

using System;
 
namespace SecureMemoryApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ObscuredInt integer = 1;
            // Как перенести выполнение приведенного ниже оператора с вызовом метода RandomizeCryptoKey()
            // в код структуры ObscuredInt таким образом, чтобы его вызов осуществлялся автоматически перед 
            // выполнением операции присваивания для идущей следом переменной?
            integer.RandomizeCryptoKey();
            integer = 2;
            Console.ReadKey();
        }
 
        public struct ObscuredInt : IEquatable<ObscuredInt>, IFormattable
        {
            private static int cryptoKey = 444444;
            private int currentCryptoKey;
            private int hiddenValue;
            private bool inited;
            private Random random;
 
            private ObscuredInt(int value)
            {
                currentCryptoKey = cryptoKey;
                hiddenValue = value;
                inited = true;
                random = new Random();
            }
 
            public static int Encrypt(int value)
            {
                return Encrypt(value, 0);
            }
 
            public static int Encrypt(int value, int key)
            {
                if (key == 0)
                {
                    return value ^ cryptoKey;
                }
                return value ^ key;
            }
 
            public static int Decrypt(int value)
            {
                return Decrypt(value, 0);
            }
 
            public static int Decrypt(int value, int key)
            {
                if (key == 0)
                {
                    return value ^ cryptoKey;
                }
                return value ^ key;
            }
 
            public void ApplyNewCryptoKey()
            {
                if (currentCryptoKey != cryptoKey)
                {
                    hiddenValue = Encrypt(InternalDecrypt(), cryptoKey);
                    currentCryptoKey = cryptoKey;
                }
            }
 
            public void RandomizeCryptoKey()
            {
                hiddenValue = InternalDecrypt();
                do
                {
                    currentCryptoKey = random.Next(int.MinValue, int.MaxValue);
                } while (currentCryptoKey == 0);
                hiddenValue = Encrypt(hiddenValue, currentCryptoKey);
            }
 
            public int GetEncrypted()
            {
                ApplyNewCryptoKey();
                return hiddenValue;
            }
 
            public void SetEncrypted(int encrypted)
            {
                inited = true;
                hiddenValue = encrypted;
            }
 
            private int InternalDecrypt()
            {
                if (!inited)
                {
                    currentCryptoKey = cryptoKey;
                    hiddenValue = Encrypt(0);
                    inited = true;
                }
 
                int decrypted = Decrypt(hiddenValue, currentCryptoKey);
 
                return decrypted;
            }
 
            #region operators, overrides, interface implementations
 
            public static implicit operator ObscuredInt(int value)
            {
                ObscuredInt obscured = new ObscuredInt(Encrypt(value));
 
                return obscured;
            }
 
            public static implicit operator int(ObscuredInt value)
            {
                return value.InternalDecrypt();
            }
 
            public static ObscuredInt operator ++(ObscuredInt input)
            {
                int decrypted = input.InternalDecrypt() + 1;
                input.hiddenValue = Encrypt(decrypted, input.currentCryptoKey);
 
                return input;
            }
 
            public static ObscuredInt operator --(ObscuredInt input)
            {
                int decrypted = input.InternalDecrypt() - 1;
                input.hiddenValue = Encrypt(decrypted, input.currentCryptoKey);
 
                return input;
            }
 
            public override bool Equals(object obj)
            {
                if (!(obj is ObscuredInt))
                    return false;
                return Equals((ObscuredInt)obj);
            }
 
            public bool Equals(ObscuredInt obj)
            {
                if (currentCryptoKey == obj.currentCryptoKey)
                {
                    return hiddenValue == obj.hiddenValue;
                }
 
                return Decrypt(hiddenValue, currentCryptoKey) == Decrypt(obj.hiddenValue, obj.currentCryptoKey);
            }
 
            public override int GetHashCode()
            {
                return InternalDecrypt().GetHashCode();
            }
 
            public override string ToString()
            {
                return InternalDecrypt().ToString();
            }
 
            public string ToString(string format)
            {
                return InternalDecrypt().ToString(format);
            }
 
            public string ToString(IFormatProvider provider)
            {
                return InternalDecrypt().ToString(provider);
            }
 
            public string ToString(string format, IFormatProvider provider)
            {
                return InternalDecrypt().ToString(format, provider);
            }
            #endregion
        }
    }
}

Решение задачи: «Альтернатива перегрузке оператора присваивания»

textual
Листинг программы
ObscuredInt integer = new ObscuredInt(1);

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.154 из 5
Похожие ответы