如何在泛型类中检查和设置特定值对象的值

本文关键字:对象 设置 检查和 泛型类 | 更新日期: 2023-09-27 18:28:31

我在存储库类中有一个方法,它为域对象设置插入元数据:

 private void SetInsertMetadata(TDomainEntity entity)
 {
      entity.InsertDT = DateTime.UtcNow;
 }

我需要检查–这个entity类是否有一个值对象列表作为属性?如果是,则在它们中的每一个中设置InsertDT

如何从泛型类进行此检查?

如何在泛型类中检查和设置特定值对象的值

在这里做一些假设。首先,你的界面看起来像这样:

public interface TDomainEntity
{
    DateTime InsertDT { get; set; }
}

你有几个实体:

public class EntityA : TDomainEntity
{
    public EntityB BValue { get; set; }
    public DateTime InsertDT { get; set; }
}
public class EntityB : TDomainEntity
{
    public DateTime InsertDT { get; set; }
}

循环遍历每个属性并设置InsertDT属性的函数可以是这样的:

private void SetInsertMetadata(TDomainEntity entity)
{
    if(entity == null) return;  //To prevent errors below
    entity.InsertDT = DateTime.UtcNow;
    //Get all properties of the entity that also implement the TDomainEntity interface
    var props = entity.GetType().GetProperties()
                    .Where(p => typeof(TDomainEntity).IsAssignableFrom(p.PropertyType));
    //Recurse through each property:
    foreach(var p in props)
    {
        SetInsertMetadata((TDomainEntity)p.GetValue(entity));
    }
}

或者你可以把最后几行合并在一起:

entity.GetType().GetProperties()
    .Where(p => typeof(TDomainEntity).IsAssignableFrom(p.PropertyType))
    .ToList()
    .ForEach(p => SetInsertMetadata((TDomainEntity)p.GetValue(entity)));

如果您还想包括IEnumerable<TDomainEntity>属性,请添加以下内容:

entity.GetType().GetProperties()
    .Where(p => typeof(IEnumerable<TDomainEntity>).IsAssignableFrom(p.PropertyType))
    .ToList()
    .ForEach(p => 
    {
        var value = (IEnumerable<TDomainEntity>)p.GetValue(entity);
        if(value == null) return;
        value.ToList().ForEach(i => SetInsertMetadata((TDomainEntity)i));
    });

假设您的类定义看起来有点像:

public class GenericClass<TDomainEntity>
{
    ...
}

您希望指定TDomainEntity从接口继承。创建一个看起来像这样的界面:

public interface IDateTimeHolder
{
    DateTime InsertTD { get; set; }
}

(根据需要命名接口)然后更新泛型类以指定泛型类型的接口:

public class GenericClass<TDomainEntity> where TDomainEntity : IDateTimeHolder
{
    string Version { get; set; }
}

还要确保传入的类实现了接口。