なので BackgroundWorker で DataContext を取得したい場合、こんな風に UI スレッドで動かしてやらないといけない。
Action action = () =>
{
var hoge = (HogeViewModel)this.DataContext;
// do something ...
}
tihs.Dispatcher.Invoke(action);
Action action = () =>
{
var hoge = (HogeViewModel)this.DataContext;
// do something ...
}
tihs.Dispatcher.Invoke(action);
// 基底クラス
public class Base {}
// サブクラス
public class SubClass : Base {}
// とあるクラス
public class Foo
{
// 実体は List だけど IEnumerable として公開
public IEnumerable Classes
{
get { return new List<SubClass>(); }
}
}
これでリフレクションを用いて、Classes プロパティが IEnumerable
var propType = typeof(Foo).GetProperty("Classes").PropertyType;
bool impl = false;
// これは false
impl = propType.IsSubclassOf(typeof(IEnumerable));
// これで IEnumerable を実装していることは判別できた
var filter = new System.Reflection.TypeFilter((t, obj) => t == (Type)obj);
impl = propType.FindInterfaces(filter, typeof(IEnumerable)) > 0;
// 最終的にはこう
impl = impl && propType.IsGenericType && propType.GetGenericParameters()[0].IsSubclassOf(typeof(Base));
かなり長ったらしくてめんどくさい。typeof(IEnumerable<Base>).IsAssignableFrom(propType)代入可能かどうかで調べたらよかったのか。
<name><![CDATA[pinzolo]]></name>こんな XML を出力したい場合、通常ならばこう書けばいい。
var nameElement= new XElement("name", new XCData(obj.Name));
でも、obj.Name が null の場合、ArgumentNullException が発生する。
var nameElement = new XElement("name");
if (obj.Name != null)
{
nameElement.SetValue(new XCData(obj.Name));
}
しかし、XObject を値にすることはできないという ArgumentException が発生した。
var nameElement = new XElement("name");
if (obj.Name != null)
{
nameElement.SetValue(new XCData(obj.Name).ToString());
}
こうなった。まあ、当たり前だ。
<name><![CDATA[pinzolo]]></name>他にも正解はあるだろうが、とりあえず正解の一つはこれのようだ。
var nameElement = new XElement("name");
if (obj.Name != null)
{
nameElement.ReplaceNodes(new XCData(obj.Name));
}
なるほど、置き換えてやるのね。
var values = Enumerable.Empty<String>();
var numbers = new List<int>() { 1, 2, 3, 4, 5 };
numbers.ConvertAll<String>(n => n.ToString() + n.ToString()).ForEach(Console.WriteLine);
結果は↓
11 22 33 44 55でも、これはList
IEnumerable<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
// IEnumerable<T>.ForEach は実装済み
numbers.Select<int, String>(n => n.ToString() + n.ToString()).ForEach(Console.WriteLine);
using System;
namespace NUnitSample
{
public class Sample
{
public int SampleMethod(string text)
{
return 0;
}
}
}
テスト用プロジェクト(NUnitSampleTest)を追加し、参照設定にプロジェクトから NUnitSample プロジェクトを、.NET から nunit.framework を追加。
テストクラス SampleTest を作成し、テストメソッドを追加。
using System;
using NUnit.Framework;
using NUnitSample;
namespace NUnitSampleTest
{
public class SampleTest
{
private Sample sample = new Sample();
[Test(Description="引数 null 時のSampleMethodテスト")]
[ExpectedException(typeof(ArgumentNullException))]
public void SampleMethodWithNullArgument()
{
this.sample.SampleMethod(null);
}
[Test(Description="数値でない引数のテスト")]
[ExpectedException(typeof(ArgumentException))]
public void SampleMethodWithInvalidArgument()
{
this.sample.SampleMethod("hoge");
}
[Test(Description="正常な引数時のテスト")]
public void SamplemethodWithValidArgument()
{
int expected = 1234;
int actual = this.sample.SampleMethod("1234");
Assert.AreEqual(expected, actual);
}
}
}
[外部ツール]→[NUnit]で実行する。
当然失敗する。
using System;
namespace NUnitSample
{
public class Sample
{
public int SampleMethod(string text)
{
if (text == null)
{
throw new ArgumentNullException("text");
}
int result = 0;
if (Int32.TryParse(text, out result))
{
return result;
}
else
{
throw new ArgumentException("text");
}
}
}
}
実行して成功するのを確認する。