如何获取实例变量的最顶层类型?
How to get the top most type of an instance variable?
假设我有一个声明为给定基数的实例变量class。我想找到该对象实际的原始类型,而不是基本类型 class。我该怎么做?
我有一个 la PostSharp 验证属性,因此反射命中是在编译时发生的,因此由于 CompileTimeValidation
方法而没有实际意义。我只是不知道该怎么做。进行 IsSubclassOf
扫描没有帮助,因为我会得到多个误报。
为了提供上下文,我有一个基本 Entity
类型。我从这个类型派生出来定义各种 Entity
类型。我用策略属性修饰这些类型,包括基础 Entity
。 PostSharp 方面在编译时验证某些策略约束。我希望能够仅使用方面验证来修饰基础 Entity
类型,以便验证 Entity
及其所有派生类型。我可以看到验证已经发生。但是,它被处理为 Entity
而不是 DerivedEntity
。为了评估 DerviedEntity
上的政策,我需要专门装饰 class。如果可能的话,我不想这样做,只装饰 Entity
.
本质上,我想将我的验证集中在基础 class 上,因为验证模式对于所有派生的 class 都是相同的。但是,派生的 classes 中的值可能会更改,我需要进行一些边界检查。
编辑:让我们添加一些代码。
[EnforceMaxLifetimePolicy]
[LifetimePolicy]
public class Entity<T>
{
public string Key { get; set; }
public T Object { get; set; }
public TimeSpan EntityLifetime
{
get
{
var lifetimePolicy =
Attribute.GetCustomAttribute(GetType(), typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
return new TimeSpan(lifetimePolicy.Hours, lifetimePolicy.Minutes, 0);
}
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
internal class LifetimePolicyAttribute : Attribute
{
public readonly short Hours;
public readonly short Minutes;
public LifetimePolicyAttribute(short hours, short minutes)
{
Hours = hours;
Minutes = minutes;
}
public LifetimePolicyAttribute()
{
Minutes = 1;
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
internal class EnforceMaxLifetimePolicyAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(MethodBase method)
{
var type = method.GetType();
var lifetimePolicy = GetCustomAttribute(type, typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
if (lifetimePolicy != null && lifetimePolicy.Hours + lifetimePolicy.Minutes / 60 > 24)
{
throw new InvalidAnnotationException($"Lifetimes can not exceed 24 hours. The lifetime on {type.FullName} is invalid.");
}
return true;
}
}
[LifetimePolicy(hours: 24, minutes: 0)]
internal class ShoppingCartEntity : Entity<ShoppingCart>
{
}
如您所见,ShoppingCartEntity 上没有 [EnforceMaxLifetimePolicy]
。它位于 class Entity
基地。但是,我仍然希望 Enforce 属性实体也适用于派生类型,这就是为什么我将 Inherited
标志保留为默认值 (true) 的原因。
我不太明白你的问题,但你总能找到答案:
1。对象实际类型(使用obj.GetType()):
if (obj.GetType() == typeof(Entity)) { ... }
2。如果对象派生自某种类型(使用 "is" 运算符):
if (obj is Entity) { ... }
您可以遍历每个基地 class 直到跌至谷底。在您要查找的属性第一次出现时停止:
var type = method.GetType();
do
{
var lifetimePolicy = GetCustomAttribute(type, typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
if (lifetimePolicy != null)
{
// process
break; // out of the do...while
}
} while ((type = type.BaseType) != null);
显然,PostSharp 消除了这种需要。它支持通过多播自动应用到派生类型。所以,lifetime 属性看起来像这样:
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
[MulticastAttributeUsage(Inheritance = MulticastInheritance.Multicast)]
internal class EnforceMaxLifetimePolicyAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(MethodBase method)
{
var type = method.DeclaringType;
var lifetimePolicy = GetCustomAttribute(type, typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
if (lifetimePolicy.Hours + lifetimePolicy.Minutes / 60 > 24)
{
throw new InvalidAnnotationException($"Lifetimes can not exceed 24 hours. The lifetime on {type.FullName} is invalid.");
}
return true;
}
}
[MulticastAttributeUsage(Inheritance = MulticastInheritance.Multicast)]
行将让 PostSharp 自动将它应用到 ShoppingCartEntity
和其他人。
假设我有一个声明为给定基数的实例变量class。我想找到该对象实际的原始类型,而不是基本类型 class。我该怎么做?
我有一个 la PostSharp 验证属性,因此反射命中是在编译时发生的,因此由于 CompileTimeValidation
方法而没有实际意义。我只是不知道该怎么做。进行 IsSubclassOf
扫描没有帮助,因为我会得到多个误报。
为了提供上下文,我有一个基本 Entity
类型。我从这个类型派生出来定义各种 Entity
类型。我用策略属性修饰这些类型,包括基础 Entity
。 PostSharp 方面在编译时验证某些策略约束。我希望能够仅使用方面验证来修饰基础 Entity
类型,以便验证 Entity
及其所有派生类型。我可以看到验证已经发生。但是,它被处理为 Entity
而不是 DerivedEntity
。为了评估 DerviedEntity
上的政策,我需要专门装饰 class。如果可能的话,我不想这样做,只装饰 Entity
.
本质上,我想将我的验证集中在基础 class 上,因为验证模式对于所有派生的 class 都是相同的。但是,派生的 classes 中的值可能会更改,我需要进行一些边界检查。
编辑:让我们添加一些代码。
[EnforceMaxLifetimePolicy]
[LifetimePolicy]
public class Entity<T>
{
public string Key { get; set; }
public T Object { get; set; }
public TimeSpan EntityLifetime
{
get
{
var lifetimePolicy =
Attribute.GetCustomAttribute(GetType(), typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
return new TimeSpan(lifetimePolicy.Hours, lifetimePolicy.Minutes, 0);
}
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
internal class LifetimePolicyAttribute : Attribute
{
public readonly short Hours;
public readonly short Minutes;
public LifetimePolicyAttribute(short hours, short minutes)
{
Hours = hours;
Minutes = minutes;
}
public LifetimePolicyAttribute()
{
Minutes = 1;
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
internal class EnforceMaxLifetimePolicyAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(MethodBase method)
{
var type = method.GetType();
var lifetimePolicy = GetCustomAttribute(type, typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
if (lifetimePolicy != null && lifetimePolicy.Hours + lifetimePolicy.Minutes / 60 > 24)
{
throw new InvalidAnnotationException($"Lifetimes can not exceed 24 hours. The lifetime on {type.FullName} is invalid.");
}
return true;
}
}
[LifetimePolicy(hours: 24, minutes: 0)]
internal class ShoppingCartEntity : Entity<ShoppingCart>
{
}
如您所见,ShoppingCartEntity 上没有 [EnforceMaxLifetimePolicy]
。它位于 class Entity
基地。但是,我仍然希望 Enforce 属性实体也适用于派生类型,这就是为什么我将 Inherited
标志保留为默认值 (true) 的原因。
我不太明白你的问题,但你总能找到答案:
1。对象实际类型(使用obj.GetType()):
if (obj.GetType() == typeof(Entity)) { ... }
2。如果对象派生自某种类型(使用 "is" 运算符):
if (obj is Entity) { ... }
您可以遍历每个基地 class 直到跌至谷底。在您要查找的属性第一次出现时停止:
var type = method.GetType();
do
{
var lifetimePolicy = GetCustomAttribute(type, typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
if (lifetimePolicy != null)
{
// process
break; // out of the do...while
}
} while ((type = type.BaseType) != null);
显然,PostSharp 消除了这种需要。它支持通过多播自动应用到派生类型。所以,lifetime 属性看起来像这样:
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
[MulticastAttributeUsage(Inheritance = MulticastInheritance.Multicast)]
internal class EnforceMaxLifetimePolicyAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(MethodBase method)
{
var type = method.DeclaringType;
var lifetimePolicy = GetCustomAttribute(type, typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
if (lifetimePolicy.Hours + lifetimePolicy.Minutes / 60 > 24)
{
throw new InvalidAnnotationException($"Lifetimes can not exceed 24 hours. The lifetime on {type.FullName} is invalid.");
}
return true;
}
}
[MulticastAttributeUsage(Inheritance = MulticastInheritance.Multicast)]
行将让 PostSharp 自动将它应用到 ShoppingCartEntity
和其他人。