public static object MakeAnalysisInstanceCore <T>(Rec rec, HashSet <Type> encountered) { var t = typeof(T); if (typeof(PipelineColumn).IsAssignableFrom(t)) { if (t.IsGenericType) { var genP = t.GetGenericArguments(); var genT = t.GetGenericTypeDefinition(); if (genT == typeof(Scalar <>)) { return(Utils.MarshalInvoke(MakeScalar <int>, genP[0], rec)); } if (genT == typeof(Vector <>)) { return(Utils.MarshalInvoke(MakeVector <int>, genP[0], rec)); } if (genT == typeof(NormVector <>)) { return(Utils.MarshalInvoke(MakeNormVector <int>, genP[0], rec)); } if (genT == typeof(VarVector <>)) { return(Utils.MarshalInvoke(MakeVarVector <int>, genP[0], rec)); } if (genT == typeof(Key <>)) { return(Utils.MarshalInvoke(MakeKey <uint>, genP[0], rec)); } if (genT == typeof(Key <,>)) { Func <Rec, PipelineColumn> f = MakeKey <uint, int>; return(f.Method.GetGenericMethodDefinition().MakeGenericMethod(genP).Invoke(null, new object[] { rec })); } if (genT == typeof(VarKey <>)) { return(Utils.MarshalInvoke(MakeVector <int>, genP[0], rec)); } if (genT == typeof(Custom <>)) { return(Utils.MarshalInvoke(MakeCustom <int>, genP[0], rec)); } } throw Contracts.Except($"Type {t} is a {nameof(PipelineColumn)} yet does not appear to be directly one of " + $"the official types. This is commonly due to a mistake by the component author and can be addressed by " + $"upcasting the instance in the tuple definition to one of the official types."); } // If it's not a pipeline column type, perhaps it is a value-tuple. if (ValueTupleUtils.IsValueTuple(t)) { var genT = t.GetGenericTypeDefinition(); var genP = t.GetGenericArguments(); Contracts.Assert(1 <= genP.Length && genP.Length <= 8); // First recursively create the sub-analysis objects. object[] subArgs = genP.Select(subType => Utils.MarshalInvoke(MakeAnalysisInstanceCore <int>, subType, rec, encountered)).ToArray(); // Next create the tuple. return(_valueTupleCreateMethod[subArgs.Length - 1].MakeGenericMethod(genP).Invoke(null, subArgs)); } else { // If neither of these, perhaps it's a supported type of property-bearing class. Either way, this is the sort // of class we have to be careful about since there could be some recursively defined types. if (!encountered.Add(t)) { throw Contracts.Except($"Recursively defined type {t} encountered."); } var func = GetContainerMaker(t, out Type[] inputTypes); object[] subArgs = inputTypes.Select(subType => Utils.MarshalInvoke(MakeAnalysisInstanceCore <int>, subType, rec, encountered)).ToArray(); encountered.Remove(t); return(func(subArgs)); } //throw Contracts.Except($"Type {t} is neither a {nameof(PipelineColumn)} subclass nor a value tuple. Other types are not permitted."); }
public static object MakeAnalysisInstanceCore <T>(Rec rec) { var t = typeof(T); if (typeof(PipelineColumn).IsAssignableFrom(t)) { if (t.IsGenericType) { var genP = t.GetGenericArguments(); var genT = t.GetGenericTypeDefinition(); if (genT == typeof(Scalar <>)) { return(Utils.MarshalInvoke(MakeScalar <int>, genP[0], rec)); } if (genT == typeof(Vector <>)) { return(Utils.MarshalInvoke(MakeVector <int>, genP[0], rec)); } if (genT == typeof(NormVector <>)) { return(Utils.MarshalInvoke(MakeNormVector <int>, genP[0], rec)); } if (genT == typeof(VarVector <>)) { return(Utils.MarshalInvoke(MakeVarVector <int>, genP[0], rec)); } if (genT == typeof(Key <>)) { return(Utils.MarshalInvoke(MakeKey <uint>, genP[0], rec)); } if (genT == typeof(Key <,>)) { Func <Rec, PipelineColumn> f = MakeKey <uint, int>; return(f.Method.GetGenericMethodDefinition().MakeGenericMethod(genP).Invoke(null, new object[] { rec })); } if (genT == typeof(VarKey <>)) { return(Utils.MarshalInvoke(MakeVector <int>, genP[0], rec)); } } throw Contracts.Except($"Type {t} is a {nameof(PipelineColumn)} yet does not appear to be directly one of " + $"the official types. This is commonly due to a mistake by the component author and can be addressed by " + $"upcasting the instance in the tuple definition to one of the official types."); } // If it's not a pipeline column type then we suppose it is a value tuple. if (t.IsGenericType && ValueTupleUtils.IsValueTuple(t)) { var genT = t.GetGenericTypeDefinition(); var genP = t.GetGenericArguments(); if (1 <= genP.Length && genP.Length <= 8) { // First recursively create the sub-analysis objects. object[] subArgs = genP.Select(subType => Utils.MarshalInvoke(MakeAnalysisInstanceCore <int>, subType, rec)).ToArray(); // Next create the tuple. return(_valueTupleCreateMethod[subArgs.Length - 1].MakeGenericMethod(genP).Invoke(null, subArgs)); } } throw Contracts.Except($"Type {t} is neither a {nameof(PipelineColumn)} subclass nor a value tuple. Other types are not permitted."); }