将对象泛型地投射到它';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。
实现这一目标的最佳方式是什么?
我建议通过引入接口来修改您的设计。
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);