【发布时间】:2017-02-28 03:39:58
【问题描述】:
假设我有一个声明为给定基类的实例变量。我想找到该对象实际上是原始的最高类型而不是基类。我该怎么做?
我有一个 PostSharp 验证属性,因此反射命中是在编译时进行的,因此由于 CompileTimeValidation 方法而没有实际意义。我只是不知道该怎么做。进行IsSubclassOf 扫描没有帮助,因为我会得到多个误报。
为了给出上下文,我有一个基本的Entity 类型。我从这种类型中派生出所有类型的Entity 类型。我用策略属性装饰这些类型,包括基本的Entity。 PostSharp 方面在编译时验证某些策略约束。我希望能够仅使用方面验证来装饰基本 Entity 类型,以便验证 Entity 及其所有派生类型。我可以看到验证已经发生。但是,它作为Entity 而不是DerivedEntity 处理。为了评估DerviedEntity 的政策,我需要专门装饰该类。如果可能,我不想这样做,只装饰Entity。
本质上,我想将验证集中在基类上,因为验证架构对于所有派生类都是相同的。但是,派生类中的值可能会发生变化,我需要进行一些边界检查。
编辑:让我们添加一些代码。
[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]。它在基类Entity 上。但是,我仍然希望 Enforce 属性实体也适用于派生类型,这就是我将 Inherited 标志保留为其默认值 (true) 的原因。
【问题讨论】:
-
obj.GetType()适合你吗? -
我想你最上面的类型总是
object:) -
@AndreiM 不幸的是没有。如果我这样做,我只会评估基于
Entity的策略属性,并且不会获得适当子类型的属性。 -
@Bigsby 你知道你可以随时查看
obj is Entity或任何其他你需要的类型。 -
你能显示一些代码吗?我很难理解实际问题。
标签: c# validation postsharp system.reflection