Что у меня есть:
public class HubGroup: HubObject
{
public HubGroup(elnGroup group)
{//do stuff}
}
public class elnGroup: elnObject
{
//has properties
}
Мое требование - когда я даю 2 типа методу, он сгенерирует функцию, которая примет объект elnGroup в качестве параметра и вернет новый экземпляр HubGroup. Я много чего пробовал, но не смог найти способ сделать это быстро (эти функции генератора будут запускаться несколько раз)
Я знаю, что вы скажете использовать дженерики, но мои типы генерируются во время выполнения . Все, что у меня есть, - это базовые классы для обоих типов, которые я могу явно объявить. Код, который вы видите ниже, - это кусочки, которые у меня есть, просто чтобы вы знали, что у меня происходит.
Я называю это так:
public class ApiDataHandler
{
//this will be called by a method to give json content for objEln
public void SoFunny<T>(string strContent, T objHub) where T : HubObject
{
if (typeof(T) == typeof(HubGroup))
{
if (string.IsNullOrEmpty(strContant))
{
throw new Exception("Cannot parse null/empty string! ---ApiDataHandler---");
}
var objEln = JsonConvert.DeserializeObject<elnGroup>(strContant);
GetHubObjectGenerator(objEln.GetType(), objHub.GetType());
}
}
}
Что я хочу создать:
Func<object,object> generator = (input) => {var bObj = input as BObject;
var aObj = new AObject(bObj);
return aObj;
}
Я сделал это: но он продолжает говорить:
InvalidOperationException: переменная 'objEln' типа 'ElnHub.HubObjectModel.elnGroup' указана из области '', но это не определено
//also inside ApiData Handler class
public Func<object, object> GetHubObjectGenerator(Type elnObjectType, Type hubObjectType)
{
ParameterExpression inputParam = Expression.Parameter(typeof(object), "input");
ParameterExpression objCastedAsEln = Expression.Parameter(elnObjectType, "objEln");
ParameterExpression objHub = Expression.Parameter(hubObjectType, "objHub");
var cast = Expression.TypeAs(inputParam, elnObjectType);
var assignCast = Expression.Assign(objCastedAsEln, cast);
var constructor = hubObjectType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { elnObjectType }, null);
var callingConstructor = Expression.New(constructor, new[] { objCastedAsEln });
var assignNewObj = Expression.Assign(objHub, callingConstructor);
var bodyBlock = Expression.Block(new[] { inputParam },
assignCast,
assignNewObj,
objHub
);
var l = Expression.Lambda<Func<object, object>>(
bodyBlock,
inputParam
);
Func<object, object> HubObjectGenerator = l.Compile();
return HubObjectGenerator;
}
Я также пробовал это, где я отправляю общие типы c, но не смог найти свой путь. Немного потеряно здесь:
public Func<T,T1> GetHubObjectGenerator<T,T1>() where T : elnObject where T1 : HubObject
{
ParameterExpression argParam = Expression.Parameter(typeof(T), "objEln");
var constructor = typeof(T1).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,null,new[] { typeof(T) },null);
Func<T, T1> HubObjectGenerator = Expression.Lambda<Func<T, T1>>(
Expression.New(constructor, new[] { argParam, }),
argParam
).Compile();
return HubObjectGenerator;
}