public void TestSinceParameterOnAttribute() { var fea = new FhirElementAttribute("test") { Since = FhirRelease.STU3 }; Assert.IsFalse(fea.AppliesToVersion(FhirRelease.DSTU1)); Assert.IsFalse(fea.AppliesToVersion(FhirRelease.DSTU2)); Assert.IsTrue(fea.AppliesToVersion(FhirRelease.STU3)); Assert.IsTrue(fea.AppliesToVersion(FhirRelease.R4)); Assert.IsTrue(fea.AppliesToVersion((FhirRelease)int.MaxValue)); fea = new FhirElementAttribute("test2") { }; Assert.IsTrue(fea.AppliesToVersion(FhirRelease.DSTU1)); Assert.IsTrue(fea.AppliesToVersion(FhirRelease.DSTU2)); Assert.IsTrue(fea.AppliesToVersion(FhirRelease.STU3)); Assert.IsTrue(fea.AppliesToVersion((FhirRelease)int.MaxValue)); var fra = new ReferencesAttribute() { Since = FhirRelease.STU3 }; Assert.IsFalse(fra.AppliesToVersion(FhirRelease.DSTU1)); Assert.IsFalse(fra.AppliesToVersion(FhirRelease.DSTU2)); Assert.IsTrue(fra.AppliesToVersion(FhirRelease.STU3)); Assert.IsTrue(fra.AppliesToVersion(FhirRelease.R4)); Assert.IsTrue(fra.AppliesToVersion((FhirRelease)int.MaxValue)); }
internal static (Type, string) ResolveElement(Type root, string element) { PropertyInfo pi = root.GetProperty(element); if (pi == null) { return(null, element); } string fhirElementName = element; FhirElementAttribute fhirElement = pi.GetCustomAttribute <FhirElementAttribute>(); if (fhirElement != null) { fhirElementName = fhirElement.Name; } Type elementType; if (pi.PropertyType.IsGenericType) { elementType = pi.PropertyType.GetGenericArguments().FirstOrDefault(); } else { elementType = pi.PropertyType.UnderlyingSystemType; } return(elementType, fhirElementName); }
void ShowPrimitiveValues() { List <String> primitives = new List <string>(); List <String> nonPrimitives = new List <string>(); foreach (FHIRAllTypes fhirType in Enum.GetValues(typeof(FHIRAllTypes)).OfType <FHIRAllTypes>()) { String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type csType = ModelInfo.GetTypeForFhirType(fhirTypeName); if (csType != null) { foreach (PropertyInfo pi in csType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { String friendlyName = pi.PropertyType.FriendlyName(); if (attribute.IsPrimitiveValue) { if (primitives.Contains(friendlyName) == false) { primitives.Add(friendlyName); } } else { if (nonPrimitives.Contains(friendlyName) == false) { nonPrimitives.Add(friendlyName); } } } } } } Trace.WriteLine($""); Trace.WriteLine($""); Trace.WriteLine($""); Trace.WriteLine($"primitives"); primitives.Sort(); foreach (String primitive in primitives) { Trace.WriteLine($"case \"{primitive}\":"); } Trace.WriteLine($""); Trace.WriteLine($""); Trace.WriteLine($""); Trace.WriteLine($"nonPrimitives"); nonPrimitives.Sort(); foreach (String nonPrimitive in nonPrimitives) { Trace.WriteLine($"case \"{nonPrimitive}\":"); } }
void OutputProperty(FhirElementAttribute attribute, CodeBlockNested item, String min, String max) { String name = attribute.Name.ToMachineName(); item .AppendCode($"Property: {name} {min}..{max}") ; }
/// <summary> /// Populate FhirApiTypes with all the Fhir Api class (resource) types that have the FhirTypeAttribute attribute. /// </summary> /// <param name="resourceType"></param> void PopulateElementDictionary(Type resourceType) { this.fhirType = resourceType; Assembly coreAsm = Assembly.GetAssembly(typeof(Hl7.Fhir.Model.Base)); foreach (PropertyInfo property in resourceType.GetProperties()) { FhirElementAttribute att = property.GetCustomAttribute <FhirElementAttribute>(false); if (att != null) { this.elements.Add(att.Name, property); } } }
internal static string GetFhirElementForResource <T>(string element) where T : Resource { MemberInfo mi = typeof(T).GetMember(element).FirstOrDefault(); if (mi != null) { FhirElementAttribute fhirElement = mi.GetCustomAttribute <FhirElementAttribute>(); if (fhirElement != null) { return(fhirElement.Name); } } return(element); }
public void TestSinceParameterOnAttribute() { var fea = new FhirElementAttribute("test") { Since = "3.2.0" }; Assert.IsFalse(fea.AppliesToVersion("1.0")); Assert.IsFalse(fea.AppliesToVersion("3.0.1")); Assert.IsTrue(fea.AppliesToVersion("3.2")); Assert.IsTrue(fea.AppliesToVersion("3.2.0")); Assert.IsTrue(fea.AppliesToVersion("3.2.1")); Assert.IsTrue(fea.AppliesToVersion("4.0.2")); Assert.IsFalse(fea.AppliesToVersion("")); Assert.IsFalse(fea.AppliesToVersion("ewout")); Assert.IsTrue(fea.AppliesToVersion(null)); fea = new FhirElementAttribute("test2") { }; Assert.IsTrue(fea.AppliesToVersion("1.0")); Assert.IsTrue(fea.AppliesToVersion("3.2.0")); Assert.IsTrue(fea.AppliesToVersion("4.0.2")); Assert.IsTrue(fea.AppliesToVersion("")); Assert.IsTrue(fea.AppliesToVersion("ewout")); Assert.IsTrue(fea.AppliesToVersion(null)); var fra = new ReferencesAttribute() { Since = "4.0.1" }; Assert.IsFalse(fra.AppliesToVersion("1.0")); Assert.IsFalse(fra.AppliesToVersion("3.0.1")); Assert.IsFalse(fra.AppliesToVersion("4.0")); Assert.IsTrue(fra.AppliesToVersion("4.0.2")); Assert.IsTrue(fra.AppliesToVersion("4.1")); Assert.IsFalse(fra.AppliesToVersion("")); Assert.IsFalse(fra.AppliesToVersion("ewout")); Assert.IsTrue(fra.AppliesToVersion(null)); }
public static PropertyInfo GetPropertyByFhirName(this Type fhirType, String fhirName) { if (fhirType is null) { throw new ArgumentNullException(nameof(fhirType)); } foreach (PropertyInfo pi in fhirType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { if (attribute.Name == fhirName) { return(pi); } } } return(null); }
private static bool IsFhirElement(MemberInfo member, object criterium) { string fhirElementName = (string)criterium; FhirElementAttribute feAtt = member.GetCustomAttribute <FhirElementAttribute>(); if (feAtt != null) { if (fhirElementName.Equals(feAtt.Name, StringComparison.InvariantCultureIgnoreCase)) { return(true); } if (fhirElementName.StartsWith(feAtt.Name, StringComparison.InvariantCultureIgnoreCase)) { if (feAtt.Choice == ChoiceType.DatatypeChoice || feAtt.Choice == ChoiceType.ResourceChoice) { AllowedTypesAttribute atAtt = member.GetCustomAttribute <AllowedTypesAttribute>(); if (atAtt != null) { foreach (Type allowedType in atAtt.Types) { var curTypeName = fhirElementName.Remove(0, feAtt.Name.Length); Type curType = ModelInfo.GetTypeForFhirType(curTypeName); if (allowedType.IsAssignableFrom(curType)) // if (link.propertyName.Equals(feAtt.Name + ModelInfo.FhirCsTypeToString[allowedType], StringComparison.InvariantCultureIgnoreCase)) { return(true); } //if (fhirElementName.Equals(feAtt.Name + ModelInfo.FhirCsTypeToString[allowedType], StringComparison.InvariantCultureIgnoreCase)) // return true; } } } } } //if it has no FhirElementAttribute, it is not a FhirElement... return(false); }
void FixElement(CodeBlockNested code, PropertyInfo pi, String varName, String retValName) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute == null) { return; } String name = pi.PropertyType.FriendlyName(); switch (name) { case "Element": case "Extension": case "ResourceReference": case "List<Extension>": case "List<Element>": case "List<ResourceReference>": return; case "bool?": code .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)") .OpenBrace() .AppendCode($"if ({varName}.{pi.Name}.Value == true)") .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = true;\");") .AppendCode($"else") .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = false;\");") .CloseBrace() ; break; case "byte[]": code .AppendCode($"if ({varName}.{pi.Name} != null)") .OpenBrace() .AppendCode($"block.OpenBrace();") .AppendCode($"block.AppendCode($\"byte[] data = new byte[]\");") .AppendCode($"block.OpenBrace();") .AppendCode($"Int32 i = 0;") .AppendCode($"while (i < {varName}.{pi.Name}.Length)") .OpenBrace() .AppendCode($"Int32 j = 0;") .AppendCode($"StringBuilder sb = new StringBuilder();") .AppendCode($"while ((i < {varName}.{pi.Name}.Length) && (j < 32))") .OpenBrace() .AppendCode($"sb.Append($\"{{{varName}.{pi.Name}[i]}}\");") .AppendCode($"if (i < {varName}.{pi.Name}.Length - 1) sb.Append(\",\");") .AppendCode($"j += 1;") .AppendCode($"i += 1;") .CloseBrace() .AppendCode($"block.AppendCode($\"{{sb.ToString()}}\");") .CloseBrace() .AppendCode($"block.CloseBrace(\";\");") .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name} = data;\");") .AppendCode($"block.CloseBrace(\";\");") .CloseBrace() ; break; case "DateTimeOffset?": code .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)") .OpenBrace() .AppendCode($"DateTimeOffset x = {varName}.{pi.Name}.Value;") .AppendCode($"block") .AppendCode($" .AppendCode($\"{retValName}.{pi.Name} = new DateTimeOffset({{x.Year}}, {{x.Month}}, {{x.Day}},\")") .AppendCode($" .AppendCode($\" {{x.Hour}}, {{x.Minute}}, {{x.Second}}, {{x.Millisecond}},\")") .AppendCode($" .AppendCode($\" new TimeSpan({{x.Offset.Hours}}, {{x.Offset.Minutes}}, {{x.Offset.Seconds}}));\")") .AppendCode($";") .CloseBrace() ; break; case "decimal?": code .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)") .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = new Nullable<decimal>((decimal) {{{varName}.{pi.Name}.Value}});\");") ; break; case "int?": code .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)") .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = new Nullable<int>((int) {{{varName}.{pi.Name}.Value}});\");") ; break; case "string": code .AppendCode($"if ({varName}.{pi.Name} != null)") .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = \\\"{{CleanString({varName}.{pi.Name})}}\\\";\");") ; break; default: if (pi.PropertyType.IsCode()) { String enumName = pi.PropertyType.GenericTypeArguments[0].FriendlyName(); code .AppendCode($"if ({varName}.{pi.Name} != null)") .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = new {name}({enumName}.{{{varName}.{pi.Name}.Value}});\");") ; } else if (pi.PropertyType.IsList()) { String source = TempName(); String target = TempName(); Type listType = pi.PropertyType.GenericTypeArguments[0]; String listTypeName = listType.FriendlyName(); code .AppendCode($"if ({varName}.{pi.Name} != null)") .OpenBrace() .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name} = new {name}();\");") .AppendCode($"foreach (var {source} in {varName}.{pi.Name})") .OpenBrace() .AppendCode($"block.OpenBrace();") .AppendCode($"block.AppendCode(\"var {target} = new {listTypeName}();\");") ; this.FixElements(code, listType, $"{source}", $"{target}"); code .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name}.Add({target});\");") .AppendCode($"block.CloseBrace();") .CloseBrace() .CloseBrace() ; } else if (pi.PropertyType.IsNullable()) { Type nullableType = pi.PropertyType.GenericTypeArguments[0]; String nullableTypeName = nullableType.FriendlyName(); if (nullableType.IsEnum) { code .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)") .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = {nullableTypeName}.{{{varName}.{pi.Name}.Value}};\");") ; } else if (nullableType.IsClass) { code .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)") .OpenBrace() .AppendCode($" block.AppendCode($\"{retValName}.{pi.Name} = new {nullableTypeName}();\");") ; this.FixElements(code, nullableType, $"{varName}.{pi.Name}", $"{retValName}.{pi.Name}"); code .CloseBrace() ; } else { throw new NotImplementedException(); } } else { String typeName = pi.PropertyType.FriendlyName(); code .AppendCode($"if ({varName}.{pi.Name} != null)") .OpenBrace() .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name} = new {typeName}();\");") ; this.FixElements(code, pi.PropertyType, $"{varName}.{pi.Name}", $"{retValName}.{pi.Name}"); code .CloseBrace() ; } return; } }
void GenerateCIMPLDataType(CodeBlockNested entryBlock, CodeBlockNested mapBlock, FHIRAllTypes fhirType) { String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type fhirCSType = ModelInfo.GetTypeForFhirType(fhirTypeName); entryBlock .BlankLine() .AppendLine($"// Fhir data element {fhirTypeName} definition") .AppendCode($"Entry: {fhirTypeName}") ; CodeBlockNested item = entryBlock.AppendBlock(); CodeBlockNested vars = entryBlock.AppendBlock(); foreach (PropertyInfo pi in fhirCSType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { String min; String max; Type csType; if (pi.PropertyType.IsList()) { min = "0"; max = "*"; csType = pi.PropertyType.GenericTypeArguments[0]; } if (pi.PropertyType.IsNullable()) { min = "0"; max = "1"; csType = pi.PropertyType.GenericTypeArguments[0]; } else { csType = pi.PropertyType; min = "1"; max = "1"; } String name = attribute.Name.ToMachineName(); item .AppendCode($"Property: {name} {min}..{max}") ; String typeName = null; String csTypeName = csType.FriendlyName(); switch (csTypeName) { case "string": OutputProperty(attribute, item, min, max); break; default: typeName = ModelInfo.GetFhirTypeNameForType(pi.PropertyType); if (String.IsNullOrEmpty(typeName)) { throw new Exception($"Can not determine fhir type for c# type {csTypeName}"); } break; } vars .BlankLine() .AppendCode($"Element: {name}") .AppendCode($"Value: {typeName}") ; // methods // .AppendCode($"case \"{attribute.Name}\":") // .OpenBrace() // .AppendCode($"ElementDefinition e = new ElementDefinition") // .OpenBrace() // .AppendCode($"Path = $\"{{parentPath}}.{attribute.Name}\",") // .AppendCode($"Short = \"{fhirType}.{attribute.Name} common attribute\",") // .AppendCode($"Min = {min},") // .AppendCode($"Max = \"{max}\"") // .CloseBrace(";") // .AppendCode($"retVal = new ElementNode(this, e, typeof({pi.PropertyType.FriendlyName()}), nameof({fhirCSType.FriendlyName()}.{pi.Name}));") // .AppendCode($"retVal.AutoGeneratedFlag = true;") // .AppendCode($"break;") // .CloseBrace(";") // ; } } }
private List <Segment> BuildSegments(string classname, List <string> chain) { var segments = new List <Segment>(); Type baseType = ModelInfo.FhirTypeToCsType[classname]; foreach (string linkString in chain) { var segment = new Segment(); segment.FhirType = baseType; var predicateRegex = new Regex(@"(?<propname>[^\[]*)(\[(?<predicate>.*)\])?"); var match = predicateRegex.Match(linkString); var predicate = match.Groups["predicate"].Value; segment.Name = match.Groups["propname"].Value; segment.Filter = ParsePredicate(predicate); var matchingFhirElements = baseType.FindMembers(MemberTypes.Property, BindingFlags.Instance | BindingFlags.Public, new MemberFilter(IsFhirElement), segment.Name); if (matchingFhirElements.Any()) { segment.Property = baseType.GetProperty(matchingFhirElements.First().Name); // TODO: Ugly repetitive code from IsFhirElement(), since that method can only return a boolean... FhirElementAttribute feAtt = segment.Property.GetCustomAttribute <FhirElementAttribute>(); if (feAtt != null) { if (feAtt.Choice == ChoiceType.DatatypeChoice || feAtt.Choice == ChoiceType.ResourceChoice) { AllowedTypesAttribute atAtt = segment.Property.GetCustomAttribute <AllowedTypesAttribute>(); if (atAtt != null) { foreach (Type allowedType in atAtt.Types) { var curTypeName = segment.Name.Remove(0, feAtt.Name.Length); Type curType = ModelInfo.GetTypeForFhirType(curTypeName); if (allowedType.IsAssignableFrom(curType)) //if (link.propertyName.Equals(feAtt.Name + ModelInfo.FhirCsTypeToString[allowedType], StringComparison.InvariantCultureIgnoreCase)) { segment.AllowedType = allowedType; } } } } } } else { segment.Property = baseType.GetProperty(segment.Name); } if (segment.Property == null) { break; } segments.Add(segment); //infoChain.Add(Tuple.Create<Type, string, PropertyInfo, Type>(baseType, propertyname, info, choiceType)); if (segment.Property.PropertyType.IsGenericType) { //For instance AllergyIntolerance.Event, which is a List<Hl7.Fhir.Model.AllergyIntolerance.AllergyIntoleranceEventComponent> baseType = segment.Property.PropertyType.GetGenericArguments().First(); } else if (segment.AllowedType != null) { baseType = segment.AllowedType; } else { baseType = segment.Property.PropertyType; } } return(segments); }
void GenerateFindCommonChild(CodeBlockNested construct, CodeBlockNested methods, FHIRAllTypes fhirType) { String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type fhirCSType = ModelInfo.GetTypeForFhirType(fhirTypeName); String methodName = $"FindChild{fhirTypeName}"; construct .AppendCode($"case \"{fhirCSType.FriendlyName()}\": return {methodName}(parentPath, childName);") ; methods .BlankLine() .SummaryOpen() .Summary($"Manually add the children of a Coding element.") .SummaryClose() .AppendCode($"ElementDefinitionNode {methodName}(String parentPath, String childName)") .OpenBrace() .AppendCode($"ElementDefinitionNode retVal;") .AppendCode($"switch (childName)") .OpenBrace() ; foreach (PropertyInfo pi in fhirCSType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { String min; String max; if (pi.PropertyType.IsList()) { min = "0"; max = "*"; } if (pi.PropertyType.IsNullable()) { min = "0"; max = "1"; } else { min = "1"; max = "1"; } String varName = $"{attribute.Name}Var"; methods .AppendCode($"case \"{attribute.Name}\":") .OpenBrace() .AppendCode($"ElementDefinition e = new ElementDefinition") .OpenBrace() .AppendCode($"Path = $\"{{parentPath}}.{attribute.Name}\",") .AppendCode($"Short = \"{fhirType}.{attribute.Name} common attribute\",") .AppendCode($"Min = {min},") .AppendCode($"Max = \"{max}\"") .CloseBrace(";") .AppendCode($"retVal = new ElementDefinitionNode(this, e, typeof({pi.PropertyType.FriendlyName()}), nameof({fhirCSType.FriendlyName()}.{pi.Name}));") .AppendCode($"retVal.AutoGeneratedFlag = true;") .AppendCode($"break;") .CloseBrace(";") ; } } methods .AppendCode($"default: return null;") .CloseBrace() .AppendCode($"this.childNodeDictionary.Add(childName, retVal);") .AppendCode($"return retVal;") .CloseBrace() ; }
void GenerateComplex(FHIRAllTypes fhirType, String genDir) { String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType); Type csType = ModelInfo.GetTypeForFhirType(fhirTypeName); if (csType == null) { return; } Trace.WriteLine($"Generating fhir complex '{fhirType}'"); CodeEditor instanceEditor = new CodeEditor(); CodeBlockNested instanceBlock = instanceEditor.Blocks.AppendBlock(); String instanceName = $"{fhirType.ToString()}_Item"; instanceBlock .AppendLine("using System;") .AppendLine("using System.Diagnostics;") .AppendLine("using System.IO;") .AppendLine("using System.Linq;") .AppendLine("using Hl7.Fhir.Model;") .BlankLine() .AppendCode("namespace FhirKhit.Maker.Common") .OpenBrace() .AppendCode($"public class {instanceName} : Complex_Item") .OpenBrace() .DefineBlock(out CodeBlockNested fields) .CloseBrace() .CloseBrace() ; foreach (PropertyInfo pi in csType.GetProperties()) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute != null) { //String min; //String max; //Type csType; if (pi.PropertyType.IsList()) { //min = "0"; //max = "*"; //csType = pi.PropertyType.GenericTypeArguments[0]; } if (pi.PropertyType.IsNullable()) { //min = "0"; //max = "1"; //csType = pi.PropertyType.GenericTypeArguments[0]; } else { //csType = pi.PropertyType; //min = "1"; //max = "1"; } } ; } //fields //; instanceEditor.Save(Path.Combine(genDir, $"{instanceName}.cs")); }
void SetFixField(PropertyInfo pi, Base retVal) { FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>(); if (attribute == null) { return; } String name = pi.PropertyType.FriendlyName(); switch (name) { case "Element": case "Extension": case "ResourceReference": case "List<Extension>": case "List<Element>": case "List<ResourceReference>": return; case "bool?": pi.SetValue(retVal, new Nullable <bool>(true)); break; case "byte[]": pi.SetValue(retVal, new byte[] { 1, 2, 3, 4 }); break; case "DateTimeOffset?": pi.SetValue(retVal, DateTimeOffset.Now); break; case "decimal?": pi.SetValue(retVal, new Nullable <Decimal>((decimal)2.1)); break; case "int?": pi.SetValue(retVal, new Nullable <Int32>(5)); break; case "string": pi.SetValue(retVal, "String"); break; default: if (name.StartsWith("Code<")) { Array enumValues = Enum.GetValues(pi.PropertyType.GenericTypeArguments[0]); var code = Activator.CreateInstance(pi.PropertyType, enumValues.GetValue(0)); pi.SetValue(retVal, code); } else if (name.StartsWith("List<")) { Type listType = pi.PropertyType.GenericTypeArguments[0]; IList list = (IList)Activator.CreateInstance(pi.PropertyType); for (Int32 i = 0; i < 5; i++) { Base item = (Base)Activator.CreateInstance(listType); SetFixFields(item); list.Add(item); } pi.SetValue(retVal, list); } else if (name.EndsWith("?")) { Type nullableType = pi.PropertyType.GenericTypeArguments[0]; if (nullableType.IsEnum) { var enumValue = Enum.GetValues(nullableType).GetValue(0); pi.SetValue(retVal, Activator.CreateInstance(pi.PropertyType, enumValue)); } else if (nullableType.IsClass) { Base nullableItem = (Base)Activator.CreateInstance(nullableType); SetFixFields(nullableItem); pi.SetValue(retVal, Activator.CreateInstance(pi.PropertyType, nullableItem)); } else { throw new NotImplementedException(); } } else { Base item = (Base)Activator.CreateInstance(pi.PropertyType); pi.SetValue(retVal, item); SetFixFields(item); } return; } }