C# OOP Stackoverflow exception
Есть базовый класс:
public abstract class BaseEvent
{
public DateTime? InternalTs { get; init; }
private string _hash;
public string Hash
{
get
{
if (String.IsNullOrEmpty(_hash))
_hash = CalcHash();
return _hash;
}
}
protected virtual string CalcHash()
{
try
{
var properties = this.GetType().GetProperties();
if (properties.Length == 0)
throw new Exception($"There're no any properties in {GetType().Name}");
if (properties.All(x => false))
throw new Exception($"All properties was null in {GetType().Name}");
StringBuilder sb = new StringBuilder();
var pp = properties.Select(x => x.GetValue(this, null));
sb.AppendJoin('_', pp);
return Utils.CreateMD5(sb.ToString());
}
catch
{
return null;
}
}
}
Есть класс наследник:
public class GotOnlineEvent : BaseEvent
{
public int EventId { get; init; }
public const int Id = 8;
private int _userId;
public int UserId
{
get => this._userId;
init => _userId = -value;
}
public int Extra { get; init; }
public DateTime? ExternalTs { get; init; }
}
То есть, я могу вызвать следующее:
var goe = new GotOnlineEvent(); Console.WriteLine(goe.Hash);
Но на этапе расчета хеша я ловлю:
Stack overflow.
Repeat 266 times:
--------------------------------
at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
...
at VkServices.source.database.models.events.BaseEvent.CalcHash()
at VkServices.source.database.models.events.BaseEvent.get_Hash()
(сократил трейсбек, чтобы не убивать ваши глаза)
BaseEvent.GetHash() берет все свойства класса наследника, засовывает их в строку типа:
$1_$2_.. и берет от нее хеш MD5, но что-то явно пошло не так.
Ответы (1 шт):
Автор решения: icYFTL
→ Ссылка
Как верно указал @Regent: при вызове всех Properties мы вызываем и Hash, которая в свою очередь вызывает CalcHash(), что приводило к бесконечной рекурсии.
Проблема решена путем:
var pp = properties.Where(x => x.Name != "Hash").Select(x => x.GetValue(this, null));
Спасибо!