Альтернатива перегрузке оператора присваивания - 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);