我认为代码可以是Linq:
foreach (var key in _dic.Keys) // for each observed key
if (_changedKeys.Contains(key)) // if it changed
foreach (var item in _dic[key]) // then for each observer
if (_webSitePage.Session[key] != null) // , as long as the value is something
item(_webSitePage.Session[key]); // call the registered delegate
在周围代码的背景下:
public class WebSiteContext
{
private WebSitePage _webSitePage;
internal void SetSessionValue<T>(string key, T value)
{
object current = _webSitePage.Session[key];
if (current != null && current.Equals(value)) return;
_webSitePage.Session[key] = value;
_changedKeys.Add(key);
}
Dictionary<string, List<Action<object>>> _dic = new Dictionary<string, List<Action<object>>>();
List<string> _changedKeys = new List<string>();
internal void WhenSessionValueChanges(string key, Action<object> action)
{
if (!_dic.ContainsKey(key)) _dic[key] = new List<Action<object>>(); // create on demand
_dic[key].Add(action);
}
internal void PageLoadComplete()
{
foreach (var key in _dic.Keys) // for each observed key
if (_changedKeys.Contains(key)) // if it changed
foreach (var item in _dic[key]) // then for each observer
if (_webSitePage.Session[key] != null) // , as long as the value is something
item(_webSitePage.Session[key]); // call the registered delegate
}
}
public class WebSitePage : System.Web.UI.Page
{
public WebSitePage()
{
this.WebSiteContext = new WebSiteContext(this);
}
public WebSiteContext WebSiteContext { get; set; }
protected override void OnLoadComplete(EventArgs e)
{
base.OnLoadComplete(e);
this.WebSiteContext.PageLoadComplete();
}
}
答案 0 :(得分:3)
可以更改为LINQ,但由于你因为副作用而调用item(...)
,我认为在这里使用LINQ是不合适的,foreach
循环更好
但你可以这样写:
foreach (var key in _dic.Keys.Where(key => _changedKeys.Contains(key))
{
foreach (var item in _dic[key])
{
var value = _webSitePage.Session[key];
if (value != null)
{
item(value);
}
}
}
答案 1 :(得分:3)
var keys = from key in _dic.Keys
where _changedKeys.Contains(key) && _webSitePage.Session[key] != null
from item in _dic[key]
select item;
foreach (var key in keys)
item(_webSitePage.Session[key]);
编辑:
以上是非常错误的。道歉。我打算使用查询理解来回答这个问题。这是一次尝试:
var tuples = from key in _dic.Keys
where _changedKeys.Contains(key) && _webSitePage.Session[key] != null
from item in _dic[key]
select new { key, item };
foreach (var t in tuples)
t.item(_webSitePage.Session[t.key]);
答案 2 :(得分:2)
var keys = _dic.Keys.Where(key => _changedKeys.Contains(key) &&
(_webSitePage.Session[key] != null));
foreach (var key in keys)
foreach (var item in _dic[key])
item(_webSitePage.Session[key]);
(第二个测试不需要在内部foreach循环中,除非item修改_webSitePage.Session)
答案 3 :(得分:2)
这缩短了一点。请注意,我移动了_webSitePage检查,因为它不依赖于item
的值:
foreach (var kvp in _dic.Where(kvp => !_changedKeys.Contains(kvp.Key) && _webSitePage.Session[kvp.Key] != null))
foreach (var item in kvp.Values) // then for each observer
item(_webSitePage.Session[key]); // call the registered delegate