Properties annotated with the SossIndexAttribute may be virtual. In this section, we review how overridden properties, explicit interface properties, and property hiding is implemented within the StateServer property index.
For example, consider:
[Serializable] abstract class Shape { [SossIndex] public abstract double Area { get; } } [Serializable] class Circle : Shape { // assume this get set somehow ... double radius = 0; public override double Area { get { return Math.PI * radius * radius; } } } [Serializable] class Rectangle : Shape { // assume these get set somehow ... double width = 0, height = 0; public override double Area { get { return width * height; } } }
NamedCache cache = CacheFactory.GetCache("Shapes"); var smallShapes = from s in cache.QueryObjects<Shape>() where s.Area < .1 select new { s.Area, s.GetType().Name }; double average = smallShapes.Select(s => s.Area).Average(); int countWhenRectangle = smallShapes.Where(s => s.Name == "Rectangle").Count(); int countWhenCircle = smallShapes.Where(s => s.Name == "Circle").Count();
When a subclass overrides a property defined in a base class, it doesn't matter if the subclass annotates the overridden property with SossIndexAttribute. When the overridden property's value is copied to StateServer's property index the overridden value is written to the property index.
.Net also supports the notion of subclasses hiding properties in their base classes. In this case, even though the properties have the same name, they are treated as distinct properties.
Consider the following example:
[Serializable] class Base { [SossIndex] public double Prop { get { return 1; } } } [Serializable] class SubClass : Base { public new double Prop { get { return -1; } } }
var queryBase = from b in cache.QueryObjects<Base>() where b.Prop > 0 select b; Console.WriteLine("Found {0} objects", queryBase.Count());
However, when you query objects while filtering against SubClass as shown here
var querySub = from s in cache.QueryObjects<SubClass>() where s.Prop < 0 select s; Console.WriteLine("Found {0} objects", querySub.Count());
If SubClass is modified by annotating Prop with SossIndexAttribute as shown here
[Serializable] class Base { [SossIndex] public double Prop { get { return 1; } } } [Serializable] class SubClass : Base { [SossIndex] public new double Prop { get { return -1; } } }
var querySub = from s in cache.QueryObjects<SubClass>() where s.Prop < 0 select s; Console.WriteLine("Found {0} objects", querySub.Count());
The SossIndexAttribute may be used with properties defined on interfaces. In that case, any type that implements the interface implicitly annotates its implementation of properties annotated on the interface. Essentially, the SossIndexAttribute annotation becomes part of the interface contract.
On the other hand, because interfaces have no implementation, the NamedCache never writes type signature information to the StateServer property index for interfaces. As a result, you cannot filter objects from a NamedCache by interface.