Я люблю шаблон ViewModel и настоятельно рекомендую его. У меня есть несколько "начала работы с ViewModel" типы, размещает в моем блоге.
Вы можете создать метод расширения для 'o' и вспомогательных классов, чтобы включить такую модель программирования, как
o.Match<A>( a => { this.A = a; return true; } )
.Match<B>( b => { this.B = b; return true; } )
.Else( () => { return false; } )
, но будьте осторожны, делая слишком много DSL-подобных. взломайте здесь, чтобы не получить API, понятный только вам.
См. также
Это не так изящно, как решение Брайана, но для этого не требуется определение нового DSL. Вы заметите, что вы повторяете следующий код:
if (o is {DataType})
{
{Property} = ({DataType})o;
return true;
}
Достаточно легко вывести этот шаблон в отдельный метод, в результате получится что-то вроде этого:
public class Container
{
public A A { get; private set; }
public B B { get; private set; }
public C C { get; private set; }
private bool TestProp<T>(object o, Action<T> f)
{
if (o is T)
return false;
f((T)o);
return true;
}
public bool StoreIfKnown(object o)
{
return
TestProp<A>(o, x => A = x) ||
TestProp<B>(o, x => B = x) ||
TestProp<C>(o, x => C = x) ||
false;
}
}
Если вы работаете со ссылочными типами, вы можете воспользоваться выводом типа со следующими настройками:
private bool TestProp<T>(T o, Action<T> f)
{
if (o == null)
return false;
f(o);
return true;
}
public bool StoreIfKnown(object o)
{
return
TestProp(o as A, x => A = x) ||
TestProp(o as B, x => B = x) ||
TestProp(o as C, x => C = x) ||
false;
}
Я играл с маленьким конструктором матчей (вдохновленный ответом Брайана ), который позволяет проверять типы, защищать предложения и возвращать результат из всего этого . Он использует вывод типа, поэтому единственное место, где вам нужно указать тип, - это то, где вы действительно хотите.
Итак, воображаемый тип C
имеет свойство IsActive
, которое мы хотим, чтобы оно было истинным
, это будет выглядеть примерно так:
var stored = Match.Against(o)
.When<A>().Then(a => { this.A = a; return true; })
.When<B>().Then(b => { this.B = b; return true; })
.When<C>(c => c.IsActive).Then(c => { this.C = c; return true; })
.Otherwise(a => false);
Что я думаю довольно удобочитаем, особенно потому, что он позволяет запускать предикат с производным типом до фактического сопоставления, что мне действительно нужно.
Код довольно длинный, так как для этого требуется несколько частично определенных классов построителей в фоновом режиме. разрешить вывод типа работать, поэтому я не могу опубликовать его здесь. Но если кто-нибудь
Барт де Смет однажды сошел с ума с сопоставлением с образцом, начиная с здесь (вплоть до части 8). Если вам когда-либо удастся пройти через весь этот контент, не должно остаться никаких вопросов для сопоставления с образцом в C #. Если есть, вероятно, на них не сможет ответить stackoverflow :)