I’m having trouble with this class, in particular the method:
public IQueryable<T> ExecuteOrderBys<T>(this IQueryable<T> source)
It says the error:
Extension method must be static
However when I made the method static, it throws other areas, specifically to this.xxx can’t be accessed in a static method.
I’m a bit confused about the return types with <T> and the return types, if someone could explain it to me and how it works I would be grateful.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
/// <summary>
/// A collection of order bys
/// </summary>
public class OrderByCollection
{
private ArrayList Orderings = new ArrayList();
public int? Skip { get; set; }
public int? Take { get; set; }
public OrderByCollection()
{
// Default skip and takes to nulls so we know if they are set or not
this.Skip = null;
this.Take = null;
}
/// <summary>
/// Add an order by to this collection
/// </summary>
public void AddOrderBy(string Field, bool Descending)
{
OrderByObj NewObj = new OrderByObj(Descending, Field);
this.Orderings.Add(NewObj);
}
/// <summary>
/// Executes the order bys
/// </summary>
public IQueryable<T> ExecuteOrderBys<T>(this IQueryable<T> source)
{
int ExecutionIndex = 0;
foreach (OrderByObj O in this.Orderings)
{
if (ExecutionIndex == 0)
{
if (O.Descending)
source = LinqHelper.OrderByDescending(source, O.Field);
else
source = LinqHelper.OrderBy(source, O.Field);
}
else
{
if (O.Descending)
source = LinqHelper.ThenByDescending((IOrderedQueryable<T>)source, O.Field);
else
source = LinqHelper.ThenBy((IOrderedQueryable<T>)source, O.Field);
}
ExecutionIndex++;
}
// Skip and take
if (this.Skip != null)
source = source.Skip(this.Skip.Value);
if (this.Take != null)
source = source.Take(this.Take.Value);
return (IOrderedQueryable<T>)source;
}
}
Edit
I’m trying to make a class that can do the following:
var q = db.tblJobHeaders;
OrderByCollection OBys = new OrderByCollection();
OBys.AddOrderBy("some field", true);
OBys.AddOrderBy("anotherfield", false);
OBys.ExecuteOrderBys(q);
You are not trying to extend
IQueryableat all by the look of your example. Removethisfrom method definition and your example should work fine.Which will make your example work:
As a side note I would not use
boolto define how the orderby’s should be sorted. The code is unclear. Use a enum or different methods instead:or:
Update
Extension methods are used to “plugin” methods to existing classes or interfaces. By writing
public IQueryable<T> ExecuteOrderBys<T>(this IQueryable<T> source)you are really saying that the method should be hooked intoIQueryable<T>. And it should therefore be accessed likemyQuery.ExecuteOrderBys.My guess is that extension methods must be static and be included in static classes to avoid confusion:
a) They are really not members of the classes or interfaces and can not access anything else than public fields/properties/methods.
b) They can extend any class. Without the restriction you could put a method call
DoSomething(this ThatObject instance)in a class calledThatObject. The problem with would be that you can’t access anything else than the public interface since it’s an extension method.The confusing possibilities would be endless 😉