I've got implicit conversion operator defined in my class to produce instance from string. I can set the variable using string literal but it fail if I try to do the same thing using reflection:
public class StringConvertable {
public StringConvertable member;
public StringConvertable(bool test = false) { if (!test) return;
member = "this is ok :)";
this.GetType().GetField(nameof(member))
.SetValue(this, "this is not ok :(");
}
public static implicit operator
StringConvertable(string s) => new StringConvertable();
}
this give me an error:
Obiektu typu 'System.String' nie można przekonwertować na typ 'Various.StringConvertable'.
Why I can't do this? What's the least invasive way to set members using reflection when I have only strings as an input?
Maybe there's a better way. Currently I solved this like that:
public class StringConvertable {
public StringConvertable member;
public int integer = int.MaxValue;
public string stringg;
public StringConvertable(bool test = false) { if (!test) return;
member = "this is ok :)";
setMember(nameof(member), "this is not ok :("); //now actually is :)
setMember(nameof(integer), "123");
setMember(nameof(integer), "abc");
setMember(nameof(stringg), "Lorem ipsum dolor sit amet");
}
private void setMember(string name, string value) {
var f = this.GetType().GetField(name);
var c = tryConvert(value, f.FieldType);
if (c.ok) f.SetValue(this, c.value);
else if(!c.found) f.SetValue(this, name);
}
public static implicit operator
StringConvertable(string s) => new StringConvertable();
private (bool found, bool ok, object value) tryConvert(string s, Type t) {
foreach (var c in converts) {
if (c.type != t) continue;
var r = c.convert(s, t);
return (true, r.ok, r.value);
}return (false, false, null);
}
private List<StringConverter> converts = new List<StringConverter>() {
new StringConverter(typeof(StringConvertable),
(s,t) => (true, (StringConvertable)s)),
new StringConverter(typeof(int),
(s,t) => (int.TryParse(s, out int v), v))
};
}
public class StringConverter {
public Type type { get; private set; }
public Converter convert { get; private set; }
public StringConverter(Type t, Converter c) {
type = t;
convert = c;
}
public delegate (bool ok, object value) Converter(string s, Type t);
}
Aucun commentaire:
Enregistrer un commentaire