C# 一般将对象强制转换为它';s';雷亚尔';类型

C# 一般将对象强制转换为它';s';雷亚尔';类型,c#,.net,generics,C#,.net,Generics,我有共享的验证逻辑,这在很大程度上取决于自定义属性,所以我需要检查每种类型的验证逻辑 为每个验证订阅服务器获取一个实例(要检查): var instance = this.ValidationProvider.GetInstanceForSubscriber(validationSubscriber); 其中,validationSubscriber是具有以下值的枚举: 人,, 检查 此时,GetInstanceForSubscriber返回object类型的实例: public object

我有共享的验证逻辑,这在很大程度上取决于自定义属性,所以我需要检查每种类型的验证逻辑

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

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
列表,其中只包含我的自定义属性,将验证规模限制为只需要的范围(仅供参考,因为与此问题不太相关)

问题

由于
instance
属于object类型,它不包含任何自定义属性(逻辑上),因此我需要将其转换为正确的类类型

实现这一点的最佳方法是什么?

一种方法是为要验证的每种类型创建重载:

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()}"
    );
}
现在,您可以将对象强制转换为
动态
,并让运行时执行分派:

object instance;
ValidateWithAttributes((dynamic)instance, 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()}"
    );
}
现在,您可以将对象强制转换为
动态
,并让运行时执行分派:

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

我建议通过引入界面来修改您的设计

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;
    }
}

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

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

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;
    }
}

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

您是否有与枚举值和类名完全匹配的名称?为什么您认为它不包含您的属性?@ShantanuGupta:不,我不赞成这样做,因为这可能/会变得很难维护(而且非常不可信)@CSharpie:var attributes=propertyInfo.GetCustomAttributes(true)行返回一个0项列表,而它对于实际类型来说工作正常。这很有意义,因为
object
不会有我的自定义属性。如果使用instance.GetType(),它永远不会返回typeof(object)枚举值和类名是否有完全匹配的名称?为什么你认为它不包含你的属性?@ShantanuGupta:No,我不赞成这样做,因为这样做可能/会变得很难维护(而且非常不可信)。@CSharpie:The
var attributes=propertyInfo.GetCustomAttributes(true)
行返回一个0项列表,而它对于实际类型来说效果很好。这很有意义,因为
object
不会有我的自定义属性。如果使用instance.GetType(),它永远不会返回typeof(object)