为了对方法进行"后处理",我想在方法中导入一个额外的函数。
如何导入一个返回匿名类型的Func
作为。select扩展方法的参数?
表达式是匿名的,如:
p => new
{
ThumnailUrl = p.PicasaEntry.Media.Thumbnails[0].Attributes["url"],
ImageUrl = p.PhotoUri
}
,需要在参数?????处使用并在。select (?????)
执行private void BindControl<T, U>(string uri, DataBoundControl target, ?????)
where T : KindQuery, new()
where U : PicasaEntity, new()
{
PicasaFeed feed = CreateFeed<T>(uri);
albumList.DataSource = GetPicasaEntries<U>(feed).Select(?????);
albumList.DataBind();
}
更新:
最后我想这样命名它:
string albumUri = PicasaQuery.CreatePicasaUri(PicasaUserID, PicasaAlbumID);
BindControls<AlbumQuery, Album>(albumUri, albumList, ?????);
string photoUri = PicasaQuery.CreatePicasaUri(PicasaUserID, PicasaAlbumID);
BindControls<PhotoQuery, Photo>(photoUri, slideShow, ?????);
其他方法如下:
private PicasaFeed CreateFeed<T>(string uri)
where T : KindQuery, new()
{
PicasaFeed feed = null;
try
{
PicasaService service = new PicasaService(PicasaApplicationName);
T query = new T();
query.BaseAddress = uri;
feed = service.Query(query);
}
catch (Exception ex)
{
//exception handling not shown
}
return feed;
}
private IEnumerable<T> GetPicasaEntries<T>(PicasaFeed feed)
where T : PicasaEntity, new()
{
if(feed == null){
return null;
}
IEnumerable<T> entries = null;
string cacheKey = feed.Id.ToString();
if(Cache.Get(cacheKey) == null)
{
entries = feed.Entries.Select(x => new T() { AtomEntry = x }).ToList();
Cache.Insert(cacheKey, entries,
null, Cache.NoAbsoluteExpiration, new TimeSpan(0,20,0));
}
return entries;
}
匿名类型实际上只设计用于本地使用。在强类型语言中,不能作为强类型的类型不被普遍使用……它们只是c#在动态世界中的小小舞蹈的一部分。
你有两个选择。
创建强类型
class Entry
{
public string ThumnailUrl { get; set; }
public string ImageUrl { get; set; }
}
然后使用:
p => new Entry
{
ThumnailUrl = p.PicasaEntry.Media.Thumbnails[0].Attributes["url"],
ImageUrl = p.PhotoUri
}
或者将其称为Object。然后使用反射来获取数据——我不推荐这样做。
能否为BindControl
添加另一个通用参数?例如:
private void BindControl<T, U, V>(string uri, DataBoundControl target,
Func<U, V> selector)
根据你的更新,我建议不要这样使用泛型。您可以通过BindControl<AlbumQuery, Album, Func<Album, dynamic>>
获得它的工作,但我建议您直接传递查询对象,利用多态性,而不是以这种方式使用泛型。
你试过这个吗,不确定它是否会工作?
private void BindControl<T, U, V>(string uri, DataBoundControl target, Func<U,V> selector)
where T : KindQuery, new()
where U : PicasaEntity, new()
{
PicasaFeed feed = CreateFeed<T>(uri);
albumList.DataSource = GetPicasaEntries<U>(feed).Select(selector);
albumList.DataBind();
}
以下是select的MSDN文档链接:
http://msdn.microsoft.com/en-us/library/bb548891.aspx
根据格式为:
Func<TSource, TResult> selector
在您的情况下,结果将是您的U参数我相信。
更新:为什么需要匿名类型。能够以函数的形式发送谓词表达式还不够吗?
private void BindControl<T, U>(string uri, DataBoundControl target, Func<U, bool> selector)
where T : KindQuery, new()
where U : PicasaEntity, new()
{
PicasaFeed feed = CreateFeed<T>(uri);
var feeds = GetPicasaEntries<U>(feed).Select(U);
}
BindControl<AlbumQuery,Album>(albumUri,albumList,p=>p.Title=="Some title");