当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - How to make a method that returns an IEnumarable of anonymous types

问题描述:

In our environment, we have a lot of large business objects. We are using our own database access layer (in this example simplified as the 'Db' class). Sometimes, we would like to retrieve a list of a select part of the available properties in a business object (e.g. only the id and last name of a customer).

In Entity framework I could use something like the following:

var keyValues = context<Customer>.Select(c => new { Id = c.ID, LastName = c.LastName, City = c.City })

But as I said before, we are not using Entity FrameWork but our own data access objects. For this example I created a database object 'Db' and a static class that can be used to fetch data from the database (now only supports one type of data object):

class Db

{

public static IEnumerable<T> GetData<T>() {

if (typeof(T) == typeof(DataClass))

{

IEnumerable<DataClass> items = new DataClass[] {

new DataClass { IntValue1 = 101, IntValue2 = 102, StringValue1 = "1_1", StringValue2 = "1_2" },

new DataClass { IntValue1 = 201, IntValue2 = 202, StringValue1 = "2_1", StringValue2 = "2_2" },

new DataClass { IntValue1 = 301, IntValue2 = 302, StringValue1 = "3_1", StringValue2 = "3_2" },

new DataClass { IntValue1 = 401, IntValue2 = 402, StringValue1 = "4_1", StringValue2 = "4_2" },

new DataClass { IntValue1 = 501, IntValue2 = 502, StringValue1 = "5_1", StringValue2 = "5_2" }

};

return items as IEnumerable<T>;

}

// else

return Enumerable.Empty<T>();

}

}

And to fetch the data from the database:

static class DataList <TSource>

{

public static IEnumerable<TSource> GetList() {

return Db.GetData<TSource>();

}

}

And the data object being used looks like this:

class DataClass

{

public int IntValue1 { get; set; }

public int IntValue2 { get; set; }

public string StringValue1 { get; set; }

public string StringValue2 { get; set; }

}

I then would like to be able to do something like this:

var items = DataList<DataClass>.GetList(x => new { Value1 = x.IntValue1 });

I started by taking a look at the method signature of the 'Select' Linq extension method that provides the same functionality and created the following method in the 'DataList' class.

public static IEnumerable<TResult> GetList<TSource, TResult>(Func<TSource, TResult> selector)

{

IEnumerable<TSource> data = Db.GetData<TSource>();

return data.Select(selector);

}

Let's forget that in this example I would first fetch the complete dataset from the database and only later simplify the dataset by only selecting one of the properties into an anonymous object.

The thing is however, that The solution as described above doesn't work. I am getting a compiler error on the line below:

var items = DataList<DataClass>.GetList(x => new { Value1 = x.IntValue1 });

The error is:

*Error 2 The type arguments for method 'AnonymousTypeTest.DataList.GetList(System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. O:\Ontwikkel\TryOuts\AnonymousTypeTest\AnonymousTypeTest\Form1.cs 21 25 AnonymousTypeTest

*

In my opinion, both TSource and TResult are known. Also specifying the type arguments is problematic, because I can't specify new { Value1 = x.IntValue1 } as a type argument.

Does anybody know what the problem is with the solution above, or have a better solution for the challenge that I described here?

Thanks in advance!

Björn

网友答案:

There is a problem in the definition of GetList method.

public static IEnumerable<TResult> GetList<TSource, TResult>(Func<TSource, TResult> selector)

You're adding additional type parameter TSource which is different from TSource defined in

 static class DataList <TSource>

You just need to remove TSource from GetList definition.

 public static IEnumerable<TResult> GetList<TResult>(Func<TSource, TResult> selector)
分享给朋友:
您可能感兴趣的文章:
随机阅读: