将对象泛型地投射到它';s';真实';类型

本文关键字:类型 真实 泛型 对象 | 更新日期: 2023-09-27 18:23:52

我有共享的验证逻辑,它在很大程度上依赖于自定义属性,所以我需要为每种类型检查这一点。

为每个验证订阅者获取一个实例(要检查):

var instance = this.ValidationProvider.GetInstanceForSubscriber(validationSubscriber);

其中validationSubscriber是具有以下值的枚举:

个人,检查

此时,GetInstanceForSubscriber返回类型为object的实例:

public object GetInstanceForSubscriber(ValidationSubscribers validationSubscriber)
{
    switch (validationSubscriber)
    {
        case ValidationSubscribers.Person:
            return new Person();
        case ValidationSubscribers.Checks:
            return new Checks();
        default:
            return null;
    }
}

调用此方法后,我检查类型:

var instanceType = instance.GetType();

然后,我阅读了(自定义)属性:

var attributes = propertyInfo.GetCustomAttributes(true);

然后,我返回一个IEnumerable<PropertyAttribute>列表,其中只包含我的自定义属性,将验证规模限制为仅必要的(仅供参考,因为与此问题不太相关)。

问题

由于instance属于对象类型,它不包含我的任何自定义属性(逻辑上),所以我需要将它强制转换为正确的Class type。

实现这一目标的最佳方式是什么?

将对象泛型地投射到它';s';真实';类型

我建议通过引入接口来修改您的设计。

public interface ICustomAttribute
{
    IEnumerable<PropertyAttribute> GetCustomAttributes(true);
}
class Person:ICustomAttribute
{
    IEnumerable<PropertyAttribute> GetCustomAttributes(true)
    {
         //Validation logic here for Person entity.
         //Encapsulate your entity level logic here.
          return propertyInfo.GetCustomAttributes(true);
    }
}
class Check:ICustomAttribute
{
    IEnumerable<PropertyAttribute> GetCustomAttributes(true)
    {
         //Validation logic here for CHECK entity
         //Encapsulate your entity level logic here.
          return propertyInfo.GetCustomAttributes(true);
    }
}
public ICustomAttribute GetInstanceForSubscriber(ValidationSubscribers validationSubscriber)
{
    //Use dependency injection to eliminate this if possible
    switch (validationSubscriber)
    {
        case ValidationSubscribers.Person:
            return new Person();
        case ValidationSubscribers.Checks:
            return new Checks();
        default:
            return null;
    }
}

现在,当您从这个方法接收到一个对象时,您将始终拥有正确的对象。

var instanceType = instance.GetCustomAttributes(true); //will give you all attributes

您可以通过利用泛型类型来进一步增强这种逻辑。看看这个。然而,这取决于您如何设计实体,因此您可以想出更好的解决方案。

一种方法是为要验证的每种类型生成重载

void ValidateWithAttributes(Person p, Attribute[] attr) {
    ...
}
void ValidateWithAttributes(Checks c, Attribute[] attr) {
    ...
}
// Add an overload to catch unexpected types
void ValidateWithAttributes(Object obj, Attribute[] attr) {
    throw new InvalidOperationException(
        $"Found an object of unexpected type {obj?.GetType()}"
    );
}

现在,您可以将对象强制转换为dynamic,并让运行时执行分派:

object instance;
ValidateWithAttributes((dynamic)instance, attributes);