我对此处回答的问题略有不同(Using reflection to retrieve a value from a list)
虽然这里批准的答案适用于select,但我想扩展它以便我可以根据条件类型从查询中获取数据。目前,我改编的代码看起来像这样
public static async Task<T> GetDataFromTable<T>(string paramName, string condition="")
{
var k = Activator.CreateInstance(typeof(T));
var mn = typeof(T).GetProperty(paramName);
var tc = typeof(T).GetProperty(condition);
if (mn == null || !ftrackData.Online)
return (T)k;
var data = GetTableData<T>();
if (!string.IsNullOrEmpty(paramName))
{
var retval = data.Select(t => mn.GetValue(t, null));
return (T)retval;
}
else
return (T)data.FirstOrDefault(t => mn.GetValue(t, null) > tc.GetType(t, null)).ToList();
}
我希望得到&#34;&gt;&#34;在最终返回更改中,取决于传递到参数列表中的其他参数。我知道我可以在else之后做一个简单的切换,但有没有办法通过插入来改变条件?
答案 0 :(得分:1)
你的代码没有任何意义。 Select
扩展方法需要Func<T, TResult>
,这意味着返回类型应为IEnumerable<TResult>
,而您将其指定为T
。
在您的问题中,您希望在同一方法中执行Select
和FirstOrDefault
,但这是不可能的,因为结果类型会有所不同。
Select
:
public static async Task<IEnumerable<TResult>> SelectData<T, TResult>(
string propertyName
)
{
if(string.IsNullOrWhiteSpace(propertyName))
{
return Enumerable.Empty<TResult>();
}
var dataTask = GetTableData<T>();
var tType = Expression.Parameter(typeof(T), "t");
var property = Expression.Property(tType, propertyName);
var selectExpression =
Expression.Lambda<Func<T, TResult>>(property, tType)
.Compile();
return (await dataTask).Select(selectExpression);
}
FirstOrDefault
:
public static async Task<T> FirstOrDefaultData<T>(
string propertyName,
string conditionName,
Func<MemberExpression, MemberExpression, BinaryExpression> comparer
)
{
if(string.IsNullOrWhiteSpace(propertyName) ||
string.IsNullOrWhileSpace(conditionName) ||
comparer == null
{
return default(T);
}
var dataTask = GetTableData<T>();
var tType = Expression.Parameter(typeof(T), "t");
var property = Expression.Property(tType, propertyName);
var condition = Expression.Property(tType, conditionName);
var binaryExpression =
Expression.Lambda<Func<T, bool>>(comparer(property, condition), tType)
.Compile();
return (await dataTask).FirstOrDefault(binaryExpression);
}
用法:
public class Foo
{
public string Bar { get; set; }
public bool Flag { get; set; }
}
var bars = SelectData<Foo, string>("Bar");
var foo = FirstOrDefaultData<Foo>("Bar",
"Flag",
(p, c) => Expression.GreaterThan(p, c));