patterncsharpMinor
Can my string to instance construction be improved?
Viewed 0 times
canimprovedconstructioninstancestring
Problem
I have a
The
I managed to get something to work however I pieced this together from googling each problem I encountered. A lot of what I have used is new to me, it's highly likely I have gone about it in an inefficient roundabout fashion.
```
for (int i = 0; i kvp = tableDict.ElementAt(i);
string s = kvp.Key;
if (Regex.IsMatch(s, @"\(([^\)]+)\)", RegexOptions.None))
// Key is "( something )" - entry is constructor
{
string sCon = s.WhitespaceRemoved();
sCon = sCon.Substring(1, sCon.Length - 2); // Remove brackets
string[] argsAsStrings = sCon.Split(',');
object[] args = argsAsStrings.Select(num => (object)int.Parse(num)).ToArray();
// I have only implemented this for the Color class.
// I assume the constructor is comprised of ints.
T item = (T)Activator.CreateInstance(typeof(T), args);
double prob = Convert.ToDouble(kvp.Value);
var entry = new RawChanceTableEntry(item, prob);
list.Add(entry);
}
else // Parse string as a property of T instead
{
string sProp = s;
Type type = typeof(T);
PropertyInfo propInfo = type.GetProperty(sProp);
object obj = Activator.CreateInstance(type);
T item = (T)propInfo.GetValue(obj, null);
double prob = Convert.ToDouble(kvp.Value);
var entry = ne
Dictionary (named tableDict) that has been parsed from JSON. The string describes the intended construction of a class T which is defined within the housing class of this code. The object is the numerical probability value that pairs up with the generated reference of T.The
string can be in either of two formats. Something encased in brackets, i.e. "(arg0, arg1, arg2, ...)", will call the constructor with these arguments. Anything else is assumed to be a name of a property of type T that returns a predefined T, i.e when T is of type Color, "Black" would lead to looking for Color.Black.I managed to get something to work however I pieced this together from googling each problem I encountered. A lot of what I have used is new to me, it's highly likely I have gone about it in an inefficient roundabout fashion.
```
for (int i = 0; i kvp = tableDict.ElementAt(i);
string s = kvp.Key;
if (Regex.IsMatch(s, @"\(([^\)]+)\)", RegexOptions.None))
// Key is "( something )" - entry is constructor
{
string sCon = s.WhitespaceRemoved();
sCon = sCon.Substring(1, sCon.Length - 2); // Remove brackets
string[] argsAsStrings = sCon.Split(',');
object[] args = argsAsStrings.Select(num => (object)int.Parse(num)).ToArray();
// I have only implemented this for the Color class.
// I assume the constructor is comprised of ints.
T item = (T)Activator.CreateInstance(typeof(T), args);
double prob = Convert.ToDouble(kvp.Value);
var entry = new RawChanceTableEntry(item, prob);
list.Add(entry);
}
else // Parse string as a property of T instead
{
string sProp = s;
Type type = typeof(T);
PropertyInfo propInfo = type.GetProperty(sProp);
object obj = Activator.CreateInstance(type);
T item = (T)propInfo.GetValue(obj, null);
double prob = Convert.ToDouble(kvp.Value);
var entry = ne
Solution
I'd compact the main loop as such:
I also create a specific RegEx for the bracket matching that should be faster as it's compiled at the class level:
for (var i = 0; i (object)int.Parse(num)).ToArray();
// I have only implemented this for the Color class.
// I assume the constructor is comprised of ints.
list.Add(new RawChanceTableEntry(
(T)Activator.CreateInstance(typeof(T), args),
Convert.ToDouble(kvp.Value)));
}
else
{
// Parse string as a property of T instead
var type = typeof(T);
list.Add(new RawChanceTableEntry(
(T)type.GetProperty(s).GetValue(Activator.CreateInstance(type), null),
Convert.ToDouble(kvp.Value)));
}
}I also create a specific RegEx for the bracket matching that should be faster as it's compiled at the class level:
private static readonly Regex brackets = new Regex(@"\(([^\)]+)\)", RegexOptions.Compiled);Code Snippets
for (var i = 0; i < tableDict.Count; i++)
{
var kvp = tableDict.ElementAt(i);
var s = kvp.Key;
// Key is "( something )" - entry is constructor
if (brackets.IsMatch(s))
{
var constructor = s.WhitespaceRemoved();
constructor = constructor.Substring(1, constructor.Length - 2); // Remove brackets
var argsAsStrings = constructor.Split(',');
var args = argsAsStrings.Select(num => (object)int.Parse(num)).ToArray();
// I have only implemented this for the Color class.
// I assume the constructor is comprised of ints.
list.Add(new RawChanceTableEntry<T>(
(T)Activator.CreateInstance(typeof(T), args),
Convert.ToDouble(kvp.Value)));
}
else
{
// Parse string as a property of T instead
var type = typeof(T);
list.Add(new RawChanceTableEntry<T>(
(T)type.GetProperty(s).GetValue(Activator.CreateInstance(type), null),
Convert.ToDouble(kvp.Value)));
}
}private static readonly Regex brackets = new Regex(@"\(([^\)]+)\)", RegexOptions.Compiled);Context
StackExchange Code Review Q#38536, answer score: 4
Revisions (0)
No revisions yet.