Skip to content

Instantly share code, notes, and snippets.

@masaedw
Created October 5, 2012 05:09
Show Gist options
  • Select an option

  • Save masaedw/3838209 to your computer and use it in GitHub Desktop.

Select an option

Save masaedw/3838209 to your computer and use it in GitHub Desktop.
C#でDynamicScope
[TestMethod]
public void DynamicScopeTest_Object()
{
var x = Utility.CreateDefault<DefaultTestClass>();
Assert.AreEqual("hoge", x.Name);
using (Utility.DynamicScope(() => x.Name, "name"))
{
Assert.AreEqual("name", x.Name);
}
Assert.AreEqual("hoge", x.Name);
}
static int GlobalVariable = 5;
[TestMethod]
public void DynamicScopeTest_Global()
{
Assert.AreEqual(5, GlobalVariable);
using (Utility.DynamicScope(() => GlobalVariable, 6))
{
Assert.AreEqual(6, GlobalVariable);
}
Assert.AreEqual(5, GlobalVariable);
}
[TestMethod]
public void DynamicScopeTest_Local()
{
var now = DateTime.Now;
var localVar = now;
using (Utility.DynamicScope(() => localVar, now.AddMinutes(1)))
{
Assert.AreEqual(now.AddMinutes(1), localVar);
}
Assert.AreEqual(now, localVar);
}
[TestMethod]
public void DynamicScopeTest_MultipleDispose()
{
var now = DateTime.Now;
var localVar = now;
using (var scope = Utility.DynamicScope(() => localVar, now.AddMinutes(1)))
{
Assert.AreEqual(now.AddMinutes(1), localVar);
scope.Dispose();
Assert.AreEqual(now, localVar);
localVar = now.AddSeconds(5);
}
Assert.AreEqual(now.AddSeconds(5), localVar);
}
public static class DynamicScope
{
public static IDisposable Create<U>(Expression<Func<U>> expression, U value)
{
return new DynamicScope<U>(expression, value);
}
}
/// <summary>
/// ダイナミックスコープをDisposableとして実現するクラス
/// </summary>
class DynamicScopeImpl<TValue> : IDisposable
{
Action ResetAction;
public DynamicScopeImpl(Expression<Func<TValue>> expression, TValue value)
{
var rhs = Expression.Parameter(typeof(TValue), "value");
var body = expression.Body;
var assign = Expression.Assign(body, rhs);
var actionExp = Expression.Lambda<Action<TValue>>(assign, rhs);
var action = actionExp.Compile();
var original = expression.Compile()();
action(value);
ResetAction = () => action(original);
}
public void Dispose()
{
if (ResetAction != null)
{
ResetAction();
ResetAction = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment