Я объясню свою проблему в гораздо большем классе на меньшем, легко следовать точному примеру. У меня довольно большой класс с множеством свойств разных типов, получение и установка соответствующей переменной класса.
public class Foo() {
int property1 { get => _property1 ; set => _property1 = value;}
string property2 { get => _property2 ; set => _property2 = value;}
Vector3 property3 { get => _property3 ; set => _property3 = value;}
bool property4 { get => _property3 ; set => _property4 = value;}
}
Я поместил 4 свойства в пример, но в реальном примере их много . Мне нужно применить logi c в наборе всех свойств, в зависимости от логического свойства property4, поэтому вместо того, чтобы писать один и тот же код во всех установщиках моих свойств, я попытался сделать вызываемый метод generi c во всех из них.
Итак, я создал перечисление:
public enum properties {
property1,
property2,
property3,
property4
}
Чтобы я мог установить свои свойства с помощью метода, который включает отражение, принимая тип свойства в качестве аргумента:
public void setLogic<T>(properties property, T value) {
//irrelevant code
}
Итак, мои сеттеры становятся:
public class Foo() {
int property1 { get => _property1 ; set { setLogic(properties.property1 , value) };}
string property2 { get => _property2 ; set { setLogic(properties.property2 , value) };}
Vector3 property3 { get => _property3 ; set { setLogic(properties.property3 , value) };}
bool property4 { get => _property4 ; set{ _property4 = value) };}
}
Моя проблема возникает, когда в моем setLogi c () вызывается установщик свойств, рекурсивно вызывающий переполнение стека. Итак, я решил topi c с логическим значением, управляемым из setLogi c (), которое контролирует, откуда вызывается сеттер. Итак, теперь мои свойства выглядят так:
public class Foo() {
int property1 {
get => _property1;
set {
if (!_calledFromSetLogic)
setLogic(properties.property1 , value);
else {
_property1 = value;
_calledFromSetLogic = false;
}
}
}
string property2 {
get => _property2;
set {
if (!_calledFromSetLogic)
setLogic(properties.property2 , value);
else {
_property2 = value;
_calledFromSetLogic = false;
}
}
}
Vector3 property3 {
get => _property3;
set {
if (!_calledFromSetLogic)
setLogic(properties.property3 , value);
else {
_property3 = value;
_calledFromSetLogic = false;
}
}
}
bool property4 { get => property4; set{ _property4 = value) };}
}
Код работает нормально, но элемент управления setter bool, чтобы избежать рекурсивности, отбрасывает все возможные чистки, полученные методом SetLogi c () generi c. . С другой стороны, я не могу установить переменные класса в методе setLogi c, потому что я обращаюсь к свойствам с отражением, поэтому, чтобы установить новое значение в logi c, я не могу избежать рекурсивного набора без логического (property.SetValue () из класса отражения устанавливает новое значение, снова вызывая набор, так что бесконечное l oop).
Если я этого не сделаю, мне придется вместо этого вставить метод setLogi c () of been generi c, копия вставлена для каждого свойства в наборе, что тоже не очень чистый код.
Нет ли для этого чистого решения, где сеттер можно передать в качестве аргумента , или метод generi c, который избегает бесконечного рекурсивного набора?
Я думал о чем-то вроде
private setLogic<T>(Action<> setterMethod, T value) {
//so that the property involved might be already in the setter?
}
или о другом типе setLogi c с классом generi c свойства, которые избегают бесконечных l oop, о которых нельзя думать.
Надеюсь, я понял.