This is a migrated thread and some comments may be shown as answers.

How to use Generic AggregateFunction with nullalbe field ?

6 Answers 88 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Cyril
Top achievements
Rank 1
Cyril asked on 06 Sep 2011, 12:51 PM
Hi,

I want to adapt a generic aggregate function to deal with null.
I tried that:

    public MainPage()
    {
        InitializeComponent();
        List<Item> items = new List<Item>();
        for (int i = 0; i < 10; i++)
        {
            if (i % 2 == 0)
            {
                items.Add(new Item() { ValueDouble = 1, ValueInt = null });
            }
            else
            {
                items.Add(new Item() { ValueDouble = null, ValueInt = 2 });
            }
        }
        this.RadGridView1.ItemsSource = items;
        this.RadGridView1.Columns[0].AggregateFunctions.Add(new MyAggregateFunction() { SourceField = "ValueDouble" });
        this.RadGridView1.Columns[0].AggregateFunctions.Add(new MyAggregateFunction() { SourceField = "ValueInt" });
    }
}
 
public class Item
{
    public double? ValueDouble { get; set; }
    public int? ValueInt { get; set; }
}

And then

public class MyAggregateFunction : EnumerableSelectorAggregateFunction
    {
        protected override string AggregateMethodName
        {
            get
            {
                return "MyAggregateMethod";
            }
        }
 
        protected override Type ExtensionMethodsType
        {
            get
            {
                return typeof(MyAggregates);
            }
        }
    }
 
    public class MyAggregates
    {
        public static double MyAggregateMethod<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
        {
                              // Some logic
                              return 0.0;
        }
    }

But I got an exception:

Aucune méthode générique 'MyAggregateMethod' sur le type 'CustomAggregateFunctionSL.MyAggregates' n'est compatible avec les arguments de type et les arguments fournis. Aucun argument de type ne doit être fourni si la méthode n'est pas générique. 

In fact, it is not only with nullable type, but with all the base type, int, double...
So why the RadGridView didn't find the MyAggregateMethod ?
It seems that it has the right prototype, I don't get it at all.

6 Answers, 1 is accepted

Sort by
0
Rossen Hristov
Telerik team
answered on 06 Sep 2011, 02:13 PM
Hello Cyril,

I am afraid that only TSource can be generic. The result cannot be generic. It has to be specified explicitly:

public static double MyAggregateMethod<TSource>(IEnumerable<TSource> source
    , Func<TSource, double?> selector)
{
    // Some logic
    return 0.0;
}

I hope this helps.

All the best,
Ross
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

0
Cyril
Top achievements
Rank 1
answered on 06 Sep 2011, 02:16 PM
Ok, but can I make a function which will accept all base type (int, double...) and all nullable type (int?, double?...).
Maybe something like

 MyAggregateMethod<TSource>(IEnumerable<TSource> source
    , Func<TSource, object?> selector)

Is this possible?
0
Rossen Hristov
Telerik team
answered on 06 Sep 2011, 02:28 PM
Hello Cyril,

I am afraid that not. See, we look for a static method by using reflection. We look for a method that is called "Something", that has specific type arguments and specific arguments. All of this depends on the particular member that the function will be applied over. So if the member is double? we will look for a method whose second argument is exactly Func<TSource, double?> selector.

We need this strong typing so our data engine can work correctly when locating and then executing these functions. If we could make the second parameter generic as well, we would have done this, trust me. There simply isn't a way for us to do it that way.

Thank you for your understanding.

Regards,
Ross
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

0
Cyril
Top achievements
Rank 1
answered on 06 Sep 2011, 02:39 PM
I understand that. The problem is that I receive data from outside, and it could be of any type, and I have to be able to used a custom aggregate.
I think I will have to list every possible case...

Thanks for your time!
0
Rossen Hristov
Telerik team
answered on 06 Sep 2011, 02:41 PM
Hi Cyril,

I am afraid that you will have. I also wish that was not the case.

Anyway, I will let you know if I manage to think of some kind of "dirty workaround hack", but I can't really promise that there exists one.

All the best,
Ross
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

0
Cyril
Top achievements
Rank 1
answered on 06 Sep 2011, 03:04 PM
FYI, here the kind of thing I have in mind:

public static class DGAggregates
    {
        private static double doGenericSum<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
        {
            if (!source.Any<TSource>())
                return 0;
            else
            {
                var values = (from i in source select selector(i)).ToList();
                double result = 0;
                foreach (var value in values)
                {
                    double toAdd  = 0;
                    double.TryParse(value.ToString(), out toAdd);
                    result += toAdd;
                }
                //var result = values.Cast<Double>().Sum();
                return result;
            }
        }
        public static double DGSum<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, double> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, double?> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, float?> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, float> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, decimal?> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, decimal> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, int> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, int?> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, bool> selector)
        {
            return doGenericSum(source, selector);
        }
        public static double DGSum<TSource>(IEnumerable<TSource> source, Func<TSource, bool?> selector)
        {
            return doGenericSum(source, selector);
        }
    }
Tags
GridView
Asked by
Cyril
Top achievements
Rank 1
Answers by
Rossen Hristov
Telerik team
Cyril
Top achievements
Rank 1
Share this question
or