【问题标题】:How to get Child Generic?如何获得 Child Generic?
【发布时间】:2020-07-17 11:40:59
【问题描述】:

我用通用类 TEntity 定义类 BaseController。

public class BaseController<TEntity> : Controller 

用途:

public class ProductController : BaseController<Product>
    {
        public ProductController(BaseService<Product> baseService)
            : base(baseService)
        {

        }

    }

类产品具有子属性关系。动态跟随 TEntity(产品类)

public partial class Product
    {

        [Key]
        public long CodeId { get; set; }



        public int Name { get; set; }

        //Config Ref
        [NotMapped]
        public ICollection<ProductDetail> ProductDetails { get; set; }
    }

public partial class ProductDetail
        {

            [Key]
            public long CodeId { get; set; }



            public int Name { get; set; }


        }

TEntity 现在是 Product。我得到了 ProductDetails 的属性。

var tEn = JsonUtilities.ConvertObjectToObject<TEntity>(obj);    

    var propsInfo = (typeof(TEntity)).GetProperties();

    var propsCollection = propsInfo.Where(x => x.PropertyType.IsGenericType
        && x.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>));


    foreach (var prop in propsCollection)
    {
        dynamic childItems = prop.GetValue(tEn);

        var genericType = prop.PropertyType.GenericTypeArguments[0];
        var tableProp = context.GetType().GetProperties().FirstOrDefault(x => x.Name == genericType.Name);

        foreach (dynamic itemChild in childItems)
        {
            // Convert here for setting some property value
            var dy = JsonUtilities.ConvertObjectToObject<dynamic>(itemChild);

            foreach (KeyValuePair<string, string> itemKey in dic)
            {
                itemChild[itemKey.Value.Trim()] = "DATA" ;  << dynamic property
            }

            // QUESTION HERE
            var itemChild2 =  JsonUtilities.ConvertObjectToObject<ABC???>(dy);  <<<<< 

        } 
    }

现在,我怎样才能再次将通用 itemChild 转换为 Class Object ProductDetail

var dy = JsonUtilities.ConvertObjectToObject<ProductDetail>(itemChild);  <<< I can not put ProductDetail here because, It's child of generic object Product.

我的 TEntity 是 Product,而在 Product 中有 ProductDetails 是 CHILD。 (为了便于理解,我使用了 Product 和 ProductDetail 名称。)

现在,TEntity 是产品。我可以得到 ProductDetail 类的 Child Instant。也许,叫'childClass'。 之后,我将“childClass”转换为动态对象,我的问题是如何从动态对象再次转换为“childClass”。

【问题讨论】:

  • 这段代码非常混乱。据我所知,您想为产品添加一些额外的动态细节。你也使用EF Core。如果这是真的,那么您可能应该使用外键并让数据库为您管理它。
  • 哦,不。与ef core没有关系。这只是一个例子。我有 TEntity 是产品,并且在产品中有 ProductDetails。 (为了便于理解,我使用了名称 Product 和 ProductDetail。)现在,我将 TEntity 称为 Product。我可以得到 ProductDetail 类的 Child Instant。也许,打电话给childClass。之后,我将 ProductDetail 转换为动态,并希望再次转换为 ProductDetail。
  • 仍然令人困惑。也许在这类例子中使用 Foo 和 Bar 是个好习惯

标签: c# asp.net .net asp.net-core model-view-controller


【解决方案1】:

您可以使用反射来调用泛型方法。

                MethodInfo method = typeof(JsonUtilities).GetMethod(nameof(ConvertObjectToObject));
                MethodInfo generic = method.MakeGenericMethod(typeof(prop.PropertyType));
                var itemChild2 = generic.Invoke(this, dy);

【讨论】:

  • 您好,谢谢,我会努力做的。谢谢 OxQ
  • 'dy',我们没有,如果我不知道如何输入ProductDetail
【解决方案2】:

您需要使用Interface。在这种情况下可能使用的每种类型(例如 ProductDetail)都应该实现该接口。在这种情况下,不需要多次转换。
我已经重述了这一点。

namespace Project
{
    class Product
    {
        public int Id {get;set;}
        public string Name {get;set;}
        public ICollection<ProductDetail> ProductDetails {get;set;}
    }

    class ProductDetail : IInjectable
    {
        public int Key {get;set;}
        public string Value {get;set;}
    }

    interface IInjectable
    {
        int Key {get;set;}
        string Value {get;set;}
    }

    class Worker
    {
        void Do<TEntity>(TEntity entity, Dictionary<int, string> dic)
        {
            typeof(TEntity)
                .GetProperties()
                .Where(p => p.PropertyType.IsGenericType &&
                            typeof(IEnumerable).IsAssignableFrom(p.PropertyType))
                .Select(p =>
                {
                    var genType = p.PropertyType
                                   .GetGenericArguments()
                                   .FirstOrDefault();
                    return new
                    {
                        Property = p,
                        GenericType = genType,
                    };
                })
                .Where(item => typeof(IInjectable).IsAssignableFrom(item.GenericType))
                .ToList()
                .ForEach(item =>
                {
                    var enumerableValue = item.Property
                                              .GetValue(entity) as IEnumerable;
                    foreach (var v in enumerableValue)
                    {
                        if (v is IInjectable injectable)
                        {
                            injectable.Value = dic[injectable.Key];
                        }
                    }
                });
        }
    }
}

【讨论】:

  • 我会试试的。谢谢@Mohammad Azhdari
猜你喜欢
  • 1970-01-01
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多