简体   繁体   中英

Cast base class to generic class of T

i have a base class called Event which is inherited by Generic class type called RequestModel now i have to convert base class object to derived class without knowing type of "T" in request model. Following is the thing that i have done. Thank you in advance for helping.

public class RequestModel<T>:Event
{
    public Guid Id { get; set; }
    public T Model{ get; set; }
    public string IpAddress { get; set; }
    public string EntityType => typeof(T).ToString();

    public override Type RequestEntityType { get { return typeof(T); }}
    public UserDataViewModel UserData { get; set; }
    public string Url { get; set; }
    public DateTime LogDate { get; set; }

    public RequestModel()
    {
        Id = Guid.NewGuid();
    }
}

public abstract class Event
{
    public abstract Type RequestEntityType { get; }
}

i have collection of event class where i add RequestModel

public List<Event> AllEvents = new List<Event>();

Here is the function where i get each event out of collection

public void RunLogEvent()
{
    foreach (var eventItem in AllEvents)
    {
        try
        {
            var mappedData = MapData(eventItem);
            _creditCardLogService.Add(mappedData);
        }
        catch (Exception ex)
        {
            continue;
        }
    }
    _unitOfWork.Commit();
}

Here is the MapData function where is type conversion to which i actually need to convert event object to RequestModel object

private CreditCardLog MapData(Event request)
{
    var b = Activator.CreateInstance(request.RequestEntityType);
    var a = CastToMyType(b, request);

    var serializer = new JavaScriptSerializer();
    var returnData = new CreditCardLog()
    {
        AppraisalFormID = ApparisalId,
        CreatedBy =null ,
        CreatedDate = a.LogDate,
        LogID = a.Id,
        Data = serializer.Serialize(a.Model)
    };
    //return returnData;
    return returnData;
}

public  RequestModel<T> CastToMyType<T>(T NeededType, object givenObject) where T : class
{
    var newObject = givenObject as RequestModel<T>;
    return newObject;
}

last function CastToMyType<T> is the casting function which i desperiately need to cast object to RequestModel<T> type which i am right now unable to do so please if anyone could help it will be great. thank you.

You can set Event class list in the T Model of RequestModel class as it is generic type.

public class RequestModel<T>
{
    public Guid Id { get; set; }
    public T Model { get; set; }
    public string IpAddress { get; set; }
    public string Url { get; set; }
    public DateTime LogDate { get; set; }
    public RequestModel()
    {
        Id = Guid.NewGuid();
    }
}

Now define the function where you can log the event.

public void LogEvent(RequestModel<List<Event>> request)
{
    foreach (var eventItem in request.Model)
    {
        try
        {
            var logData = new CreditCardLog()
            {
                AppraisalFormID = ApparisalId,
                CreatedBy = "UserID",
                CreatedDate = request.LogDate,
                LogID = Guid.NewGuid(),
                Data = new JavaScriptSerializer().Serialize(eventItem)
            };
            _creditCardLogService.Add(logData);
        }
        catch (Exception ex)
        {
            continue;
        }
    }
}

To convert model to RequestModel you can also create an extension method.

public static RequestModel<T> ToRequestModel<T>(this T model)
{
    return new RequestModel<T>()
    {
        Id = Guid.NewGuid(),
        Model = model
        // assign other property value
    };
}

Now, you can convert the list of event to RequestModel by calling ToRequestModel method.

List<Event> ev = new List<Event>();
var request = ev.ToRequestModel();
LogEvent(request);

Also, if there is different types of Event then you should inherit abstract Event class in those Event classes instead of RequestModel class.

You could invoke your method via reflection.

MethodInfo method = typeof(Example).GetMethod("CastToMyType");
MethodInfo generic = method.MakeGenericMethod(e.RequestEntityType);
generic.Invoke(this, new object[] { e.RequestEntityType, e });

see the fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM