Should pattern matching in C# 7 work with generics? - c#

I have a simple case where I want to use pattern matching to identify the algorithm I need to use to perform a collision test between two generic Octrees. My basic case is two Octrees of triangles. The skeleton of the code is.
public class Triangle {
public static bool
Intersects
( IReadOnlyList<Triangle> ta
, IReadOnlyList<Triangle> tb)
{
...
}
}
public class Octree<T> {
public bool Intersects<U>(Octree<U> other)
{
if (this is Octree<Triangle> ota && other is Octree<Triangle> otb)
{
return ota.Intersects( otb, Triangle.Intersects );
}
throw new NotImplementedException();
}
public bool Intersects<U>
( Octree<U> other
, Func<IReadOnlyList<T>, IReadOnlyList<U>, bool> intersectsLeaves
)
{
...
}
}
but results in the below error.
Error CS8121
An expression of type Octree<T> cannot be handled by a pattern of type
Octree<Triangle>.
Of course I can just use typeof(U) and typeof(T) to do the tests but I thought the above should really work. Why doesn't it?

Pattern matching in C# 7.0 has a requirement stating that there must be an explicit or implicit conversion from the left-hand-side type to the right-hand-side type.
In C# 7.1, the spec will be expanded so that either the left-hand-side or the right-hand-side can be an open type.

its a bug. take a look at this:
https://github.com/dotnet/roslyn/issues/16195

There is a work around to the bug/feature. You can use the Try* pattern with inline declared outvariables.
bool TryIs<TU>(object t, out TU u)
{
if (t is TU uu)
{
u = uu;
return true;
}
u = default(TU);
return false;
}
then you can use it like
public bool Intersects<U>(Octree<U> other)
{
if ( TryIs<Octree<Triangle>>(out var ota) && TryIs<Octree<Triangle>>(out var otb))
{
return ota.Intersects( otb, Triangle.Intersects );
}
throw new NotImplementedException();
}

Related

Lambda expression "=>"

I'm trying to understand a code but I can't understand what 'p' var is.
public Prediction(Game kkk,bool checkit, params State[] checkStates)
: base(game, p => Manager.method(kkk, p))
{
this.checkit = checkit;
this.checkStates = checkStates;
}
The second class:
public PiratePrediction(Game game, System.Func<Pirate, T> valueExtractor)
{
this.game = game;
this.valueExtractor = valueExtractor;
this.predictedValues = new Dictionary<Pirate, T>();
this.totalPredictions = 0;
this.correctPredictions = 0;
}
found the class you're using on https://github.com/YoavKa/Skillz2016/blob/f23d25eed4baa9786cf517583ee867075a2f0505/API/Prediction/PiratePrediction.cs
the valueExtractor lambda is used from Update, and p comes from the keys of predictedValues dictionary.
public virtual void Update()
{
foreach (var pair in this.predictedValues)
{
if (pair.Key.State != PirateState.Lost && !EqualityComparer<T>.Default.Equals(pair.Value, default(T)))
{
this.totalPredictions++;
if (this.valueExtractor(pair.Key).Equals(pair.Value))
this.correctPredictions++;
}
}
this.predictedValues.Clear();
}
the p comes from the call to Predict method of PiratePrediction class. Because it's added to the predictedValues array.
public T Predict(Pirate p)
{
if (this.predictedValues.ContainsKey(p))
return this.predictedValues[p];
T predictedValue = this.predict(p);
if (EqualityComparer<T>.Default.Equals(predictedValue, default(T)))
return default(T);
this.predictedValues.Add(p, predictedValue);
return predictedValue;
}
p is a parameter being passed into your method. A Func<T, TOut> is a delegate, meaning a method signature.
Consider the following:
private class DisplayClass
{
public readonly Game kkk;
public DisplayyClass(Game kkk) { this.kkk = kkk; }
public T handler(Pirate p) { return Manager.method(kkk, p); }
}
public Prediction(Game kkk,bool checkit, params State[] checkStates)
: base(game, new DisplayClass(kkk).handler)
{
this.checkit= checkit;
this.checkStates = checkStates;
}
This is what the compiler does to your code when interpreting lambdas - it may be a good idea to pass your code through a decompiler to see the exact phrasing.
The p variable, as you can see in the expanded code, is a parameter into the method, and lambdas are just a shorthand way to pass methods which can then be invoked in other code.
// Somewhere in the base class...
void ExtractValue(Pirate p)
{
// ...
T value = this.valueExtractor(p);
// ...
}
When thus invoked, p will be the value passed in by that other code, and by definition of Func<Pirate, T>, will be of type Pirate.
Keep in mind that the code you're passing a lambda to can invoke the code inside your lambda multiple times, such as is the case with .Select. I suggest not only reading up on lambdas, but also their extensive use in the Linq namespace
A lambda expression is a declaration of an anonymous method. So imagine that this:
p => Manager.method(kkk, p)
is equal to this:
private T SomeMethod<T>(Pirate p)
{
return Manager.method(kkk, p);
}
You wouldn't be able to do the second snippet in your situation, however, because kkk is a local variable from the scope of where the lambda expression was declared, which means that while the lambda can use kkk, an explicit method declaration can't (See Closure). This is just one benefit of lambdas over declared methods.

Conditional typing in generic method

Consider the following (heavily simplified) code:
public T Function<T>() {
if (typeof(T) == typeof(string)) {
return (T) (object) "hello";
}
...
}
It's kind of absurd to first cast to object, then to T. But the compiler has no way of knowing that the previous test assured T is of type string.
What is the most elegant, idiomatic way of achieving this behavior in C# (which includes getting rid of the stupid typeof(T) == typeof(string), since T is string can't be used)?
Addendum: There is no return type variance in .net, so you can't make a function overload to type string (which, by the way, is just an example, but one reason why association end redefinition in polymorphism, e.g. UML, can't be done in c#). Obviously, the following would be great, but it doesn't work:
public T Function<T>() {
...
}
public string Function<string>() {
return "hello";
}
Concrete Example 1: Because there's been several attacks to the fact that a generic function that tests for specific types isn't generic, I'll try to provide a more complete example. Consider the Type-Square design pattern. Here follows a snippet:
public class Entity {
Dictionary<PropertyType, object> properties;
public T GetTypedProperty<T>(PropertyType p) {
var val = properties[p];
if (typeof(T) == typeof(string) {
(T) (object) p.ToString(this); // magic going here
}
return (T) TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(val);
}
}
Concrete Example 2: Consider the Interpreter design pattern:
public class Expression {
public virtual object Execute() { }
}
public class StringExpression: Expression {
public override string Execute() { } // Error! Type variance not allowed...
}
Now let's use generics in Execute to allow the caller to force a return type:
public class Expression {
public virtual T Execute<T>() {
if(typeof(T) == typeof(string)) { // what happens when I want a string result from a non-string expression?
return (T) (object) do_some_magic_and_return_a_string();
} else if(typeof(T) == typeof(bool)) { // what about bools? any number != 0 should be True. Non-empty lists should be True. Not null should be True
return (T) (object) do_some_magic_and_return_a_bool();
}
}
}
public class StringExpression: Expressiong {
public override T Execute<T>() where T: string {
return (T) string_result;
}
}
If you're making these types of checks in a generic method, I'd rethink your design. The method is obviously not truly generic - if it were, you wouldn't need specific type checking...
Situations like this typically can be handled more cleanly by a redesign. One alternative is often to provide an overload of the appropriate type. Other design alternatives which avoid the type-specific behavior exist, as well, such as Richard Berg's suggestion of passing in a delegate.
using System;
using System.Collections.Generic;
using System.Linq;
namespace SimpleExamples
{
/// <summary>
/// Compiled but not run. Copypasta at your own risk!
/// </summary>
public class Tester
{
public static void Main(string[] args)
{
// Contrived example #1: pushing type-specific functionality up the call stack
var strResult = Example1.Calculate<string>("hello", s => "Could not calculate " + s);
var intResult = Example1.Calculate<int>(1234, i => -1);
// Contrived example #2: overriding default behavior with an alternative that's optimized for a certain type
var list1 = new List<int> { 1, 2, 3 };
var list2 = new int[] { 4, 5, 6 };
Example2<int>.DoSomething(list1, list2);
var list1H = new HashSet<int> { 1, 2, 3 };
Example2<int>.DoSomething<HashSet<int>>(list1H, list2, (l1, l2) => l1.UnionWith(l2));
}
}
public static class Example1
{
public static TParam Calculate<TParam>(TParam param, Func<TParam, TParam> errorMessage)
{
bool success;
var result = CalculateInternal<TParam>(param, out success);
if (success)
return result;
else
return errorMessage(param);
}
private static TParam CalculateInternal<TParam>(TParam param, out bool success)
{
throw new NotImplementedException();
}
}
public static class Example2<T>
{
public static void DoSomething(ICollection<T> list1, IEnumerable<T> list2)
{
Action<ICollection<T>, IEnumerable<T>> genericUnion = (l1, l2) =>
{
foreach (var item in l2)
{
l1.Add(item);
}
l1 = l1.Distinct().ToList();
};
DoSomething<ICollection<T>>(list1, list2, genericUnion);
}
public static void DoSomething<TList>(TList list1, IEnumerable<T> list2, Action<TList, IEnumerable<T>> specializedUnion)
where TList : ICollection<T>
{
/* stuff happens */
specializedUnion(list1, list2);
/* other stuff happens */
}
}
}
/// I confess I don't completely understand what your code was trying to do, here's my best shot
namespace TypeSquarePattern
{
public enum Property
{
A,
B,
C,
}
public class Entity
{
Dictionary<Property, object> properties;
Dictionary<Property, Type> propertyTypes;
public T GetTypedProperty<T>(Property p)
{
var val = properties[p];
var type = propertyTypes[p];
// invoke the cast operator [including user defined casts] between whatever val was stored as, and the appropriate type as
// determined by the domain model [represented here as a simple Dictionary; actual implementation is probably more complex]
val = Convert.ChangeType(val, type);
// now create a strongly-typed object that matches what the caller wanted
return (T)val;
}
}
}
/// Solving this one is a straightforward application of the deferred-execution patterns I demonstrated earlier
namespace InterpreterPattern
{
public class Expression<TResult>
{
protected TResult _value;
private Func<TResult, bool> _tester;
private TResult _fallback;
protected Expression(Func<TResult, bool> tester, TResult fallback)
{
_tester = tester;
_fallback = fallback;
}
public TResult Execute()
{
if (_tester(_value))
return _value;
else
return _fallback;
}
}
public class StringExpression : Expression<string>
{
public StringExpression()
: base(s => string.IsNullOrEmpty(s), "something else")
{ }
}
public class Tuple3Expression<T> : Expression<IList<T>>
{
public Tuple3Expression()
: base(t => t != null && t.Count == 3, new List<T> { default(T), default(T), default(T) })
{ }
}
}
Can you use as here?
T s = "hello" as T;
if(s != null)
return s;
I can't think of an "elegant" way to do this. As you say, the compiler can't know that the conditional has ensured that the type of T is string. As a result, it has to assume that, since there's no generalized way to convert from string to T, it's an error. object to T might succeed, so the compiler allows it.
I'm not sure I'd want an elegant way to express this. Although I can see where it'd be necessary to do explicit type checks like this in some situations, I think I'd want it to be cumbersome because it really is a bit of a hack. And I'd want it to stick out: "Hey! I'm doing something weird here!"
Ok, I took a run at it from several different angles and came up short. I would have to conclude that if your current implementation gets the job done you should take the win and move on. Short of some arcane emissions what you got is what you get.
But the compiler has no way of knowing
that the previous test assured T is of
type string.
Umm.... If I am not mistaken, generics is just code gen. The compiler generates a matching method for each distinct type found in the calling methods. So the compiler does know the type argument for the overload being called. Again; If I am not mistaken.
But overall, i think you are misusing the generic in this case, from what I can see, and as others have stated, there are more appropriate solutions..... which are unnamable unless you post code that completely specifies your requirements.
just my 2 pesos...

C# Generics and Casting Issue

I am having trouble casting an object to a generic IList. I have a group of in statements to try to work around this, but there has to be a better way to do this.
This is my current method:
string values;
if (colFilter.Value is IList<int>)
{
values = BuildClause((IList<int>)colFilter.Value, prefix);
}
else if (colFilter.Value is IList<string>)
{
values = BuildClause((IList<string>)colFilter.Value, prefix);
}
else if (colFilter.Value is IList<DateTime>)
{
values = BuildClause((IList<DateTime>)colFilter.Value, prefix);
}
else if (...) //etc.
What I want to do is this:
values = BuildClause((IList<colFilter.ColumnType>)colFilter.Value, prefix);
or
values = BuildClause((IList<typeof(colFilter.ColumnType)>)colFilter.Value, prefix);
or
values = BuildClause((IList<colFilter.ColumnType.GetType()>)colFilter.Value, prefix);
Each of these produces this compiler error:
The type or namespace name 'colFilter' could not be found (are you missing a using directive or an assembly reference?)
In my example, colFilter.ColumnType is int, string, datetime, etc. I am not sure why this does not work.
Any ideas?
EDIT: This is C#2.0
EDIT #2
Here is the BuildClause method (I have overloads for each type):
private static string BuildClause(IList<int> inClause, string strPrefix)
{
return BuildClause(inClause, strPrefix, false);
}
private static string BuildClause(IList<String> inClause, string strPrefix)
{
return BuildClause(inClause, strPrefix, true);
}
private static string BuildClause(IList<DateTime> inClause, string strPrefix)
{
return BuildClause(inClause, strPrefix, true);
}
//.. etc for all types
private static string BuildClause<T>(IList<T> inClause, string strPrefix, bool addSingleQuotes)
{
StringBuilder sb = new StringBuilder();
//Check to make sure inclause has objects
if (inClause.Count > 0)
{
sb.Append(strPrefix);
sb.Append(" IN(");
for (int i = 0; i < inClause.Count; i++)
{
if (addSingleQuotes)
{
sb.AppendFormat("'{0}'", inClause[i].ToString().Replace("'", "''"));
}
else
{
sb.Append(inClause[i].ToString());
}
if (i != inClause.Count - 1)
{
sb.Append(",");
}
}
sb.Append(") ");
}
else
{
throw new Exception("Item count for In() Clause must be greater than 0.");
}
return sb.ToString();
}
There's no way to relate method overloading and generics: although they look similar, they are very different. Specifically, overloading lets you do different things based on the type of arguments used; while generics allows you to do the exact same thing regardless of the type used.
If your BuildClause method is overloaded and every overload is doing something different (not just different by the type used, but really different logic, in this case - choosing whether or not to add quotes) then somewhere, ultimately, you're gonna have to say something like "if type is this do this, if type is that do that" (I call that "switch-on-type").
Another approach is to avoid that "switch-on-type" logic and replace it with polymorphism. Suppose you had a StringColFilter : ColFilter<string> and a IntColFilter : ColFilter<int>, then each of them could override a virtual method from ColFilter<T> and provide its own BuildClause implementation (or just some piece of data that would help BuildClause process it). But then you'd need to explicitly create the correct subtype of ColFilter, which just moves the "switch-on-type" logic to another place in your application. If you're lucky, it'll move that logic to a place in your application where you have the knowledge of which type you're dealing with, and then you could explicitly create different ColFilters at different places in your application and process them generically later on.
Consider something like this:
abstract class ColFilter<T>
{
abstract bool AddSingleQuotes { get; }
List<T> Values { get; }
}
class IntColFilter<T>
{
override bool AddSingleQuotes { get { return false; } }
}
class StringColFilter<T>
{
override bool AddSingleQuotes { get { return true; } }
}
class SomeOtherClass
{
public static string BuildClause<T>(string prefix, ColFilter<T> filter)
{
return BuildClause(prefix, filter.Values, filter.AddSingleQuotes);
}
public static string BuildClause<T>(string prefix, IList<T> values, bool addSingleQuotes)
{
// use your existing implementation, since here we don't care about types anymore --
// all we do is call ToString() on them.
// in fact, we don't need this method to be generic at all!
}
}
Of course this also gets you to the problem of whether ColFilter should know about quotes or not, but that's a design issue and deserves another question :)
I also stand by the other posters in saying that if you're trying to build something that creates SQL statements by joining strings together, you should probably stop doing it and move over to parameterized queries which are easier and, more importantly, safer.
What does the function BuildClause() look like.
It seems to me that you can create BuildClause() as an extension method on IList, and you can append the values together. I assume that you just want to call .ToString() method on different types.
If you use generics properly in C# 3.0, you can achieve what you need through implicit typing (int C# 2.0 you might need to specify the type). If your BuildClause method is made generic, it should automatically take on whatever type is passed in to its generic parameter(s):
public IList<T> BuildClause<T>(IList<T> value, object prefix)
{
Type type = typeof(T);
if (type == typeof(string))
{
// handle string
}
else if (type == typeof(int))
{
// handle int
}
// ...
}
public class ColumnFilter<T>:
where T: struct
{
public IList<T> Value { get; set; }
}
var colFilter = new ColumnFilter<string>
{
Value = new { "string 1", "string 2", "string 3" }
}
IList<string> values = BuildClause(colFilter.Value, prefix);
With generics, you can drop the ColumnType property of your ColumnFilter. Since it is generic, along with your BuildClause method, you are easily able to determine the type by doing typeof(T).
I am having trouble casting an object to a generic
Casting is a run-time operation.
Generic is compile-time information.
Don't cross the streams.
Also - if you used a decent sql parameterization generator - it will add the single quotes for you.
I don't understand the question. It works for me. It could be as simple as droping the cast? What am I missing?
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1 {
class Foo<T> : List<T> {
}
class Program {
static void Main(string[] args) {
var a = new Foo<int>();
a.Add(1);
var b = new Foo<string>();
b.Add("foo");
Console.WriteLine(BuildClause(a, "foo", true));
Console.WriteLine(BuildClause(b, "foo", true));
}
private static string BuildClause<T>(IList<T> inClause, string strPrefix, bool addSingleQuotes) {
StringBuilder sb = new StringBuilder();
//Check to make sure inclause has objects
if (inClause.Count == 0)
throw new Exception("Item count for In() Clause must be greater than 0.");
sb.Append(strPrefix).Append(" IN(");
foreach (var Clause in inClause) {
if (addSingleQuotes)
sb.AppendFormat("'{0}'", Clause.ToString().Replace("'", "''"));
else
sb.Append(Clause.ToString());
sb.Append(',');
}
sb.Length--;
sb.Append(") ");
return sb.ToString();
}
}
}
The type for the IList must be known at compile time. Depending on what you want to do, you might be able to cast the list to an IList or IEnumerable (without generics) and then iterate over the objects

Whats a fast way to check that reference is a specific generic type?

If I have a method with a parameter that's an interface, whats the fasts way to see if the interface's reference is of a specific generic type?
More specifically, if I have:
interface IVehicle{}
class Car<T> : IVehicle {}
CheckType(IVehicle param)
{
// How do I check that param is Car<int>?
}
I'm also going to have to cast after the check. So if there is a way to kill 2 birds with one stone on this one let me know.
To check if param is a Car<int> you can use "is" and "as" as normal:
CheckType(IVehicle param)
{
Car<int> car = param as Car<int>;
if (car != null)
{
...
}
}
Or, you can just do:
if(param is Car<int>)
{
// Hey, I'm a Car<int>!
}
Why not make this generic?
interface IVehicle{}
class Car<T> : IVehicle {
public static bool CheckType(IVehicle param)
{
return param is Car<T>;
}
}
...
Car<string> c1 = new Car<string>();
Car<int> c2 = new Car<int>();
Console.WriteLine(Car<int>.CheckType(c1));
Console.WriteLine(Car<int>.CheckType(c2));
The code differs quite dramatically depending on whether you want to know, if the reference is based on a generic type prototype, or a specialized one.
The specialized one is easy, you can just use is:
CheckType(IVehicle param)
{
var isofYourType = param is Car<int>;
...
}
or a safe cast, as shown before:
CheckType(IVehicle param)
{
var value = param as Car<int>;
if(value != null)
...
}
In case you wanted to know whether yur var is just some specialization of Car<T>, things get really ugly.
And the last you should thing to worry about is speed in this case, because that's gonna be even uglier than the code g:
class Car<T>
{ }
interface IVehicle { }
class YourCar : Car<int>, IVehicle
{ }
static bool IsOfType(IVehicle param)
{
Type typeRef = param.GetType();
while (typeRef != null)
{
if (typeRef.IsGenericType &&
typeRef.GetGenericTypeDefinition() == typeof(Car<>))
{
return true;
}
typeRef = typeRef.BaseType;
}
return false;
}
static void Main(string[] args)
{
IVehicle test = new YourCar();
bool x = IsOfType(test);
}
I often find that if my code requires me to write checks for specific types, I'm probably doing something wrong. You didn't give us enough context for us to give advice on this, though.
Does this meet your needs?
Car<int> carOfInt = param as Car<int>;
if (carOfInt != null)
{
// .. yes, it's a Car<int>
}
Use the "as" operator to do it all in one shot. "as" will return either an object of the type you want, or null if what you're checking against doesn't match. This will only work for reference types, though.
interface IVehicle { }
class Car<T> : IVehicle
{
static Car<int> CheckType(IVehicle v)
{
return v as Car<int>;
}
}
The "is" operator will let you test to see if v is an instance of Car<int>.

C# Lambda Expressions or Delegates as a Properties or Arguments

I'm looking to create an ValidationRule class that validates properties on an entity type object. I'd really like to set the name of the property to inspect, and then give the class a delegate or a lambda expression that will be evaluated at runtime when the object runs its IsValid() method. Does anyone have a snippet of something like this, or any ideas on how to pass an anonymous method as an argument or property?
Also, I'm not sure if I'm explaining what I'm trying to accomplish so please ask questions if I'm not being clear.
Really, what you want to use is Func<T,bool> where T is the type of the item you want to validate. Then you would do something like this
validator.AddValidation(item => (item.HasEnoughInformation() || item.IsEmpty());
you could store them in a List<Func<T,bool>>.
class ValidationRule {
public delegate bool Validator();
private Validator _v;
public ValidationRule(Validator v) { _v = v; }
public Validator Validator {
get { return _v; }
set { _v = value; }
}
public bool IsValid { get { return _v(); } }
}
var alwaysPasses = new ValidationRule(() => true);
var alwaysFails = new ValidationRule(() => false);
var textBoxHasText = new ValidationRule(() => textBox1.Text.Length > 0);
That should get you started. But, really, inheritance is far more appropriate here. The problem is simply that the Validator doesn't have access to any state that it doesn't close over, this means that it isn't as reusable as say ValidationRules that contain their own state. Compare the following class to the previous definition of textBoxHasText.
interface IValidationRule {
bool IsValid { get; }
}
class BoxHasText : IValidationRule {
TextBox _c;
public BoxHasText(TextBox c) { _c = c; }
public bool IsValid {
get { return _c.Text.Length > 0; }
}
}
Well, simply, if you have an Entity class, and you want to use lambda expressions on that Entity to determine if something is valid (returning boolean), you could use a Func.
So, given an Entity:
class Entity
{
public string MyProperty { get; set; }
}
You could define a ValidationRule class for that like this:
class ValidationRule<T> where T : Entity
{
private Func<T, bool> _rule;
public ValidationRule(Func<T, bool> rule)
{
_rule = rule;
}
public bool IsValid(T entity)
{
return _rule(entity);
}
}
Then you could use it like this:
var myEntity = new Entity() { MyProperty = "Hello World" };
var rule = new ValidationRule<Entity>(entity => entity.MyProperty == "Hello World");
var valid = rule.IsValid(myEntity);
Of course, that's just one possible solution.
If you remove the generic constraint above ("where T : Entity"), you could make this a generic rules engine that could be used with any POCO. You wouldn't have to derive a class for every type of usage you need. So if I wanted to use this same class on a TextBox, I could use the following (after removing the generic constraint):
var rule = new ValidationRule<TextBox>(tb => tb.Text.Length > 0);
rule.IsValid(myTextBox);
It's pretty flexible this way. Using lambda expressions and generics together is very powerful. Instead of accepting Func or Action, you could accept an Expression> or Expression> and have direct access to the express tree to automatically investigate things like the name of a method or property, what type of expression it is, etc. And people using your class would not have to change a single line of code.
something like:
class ValidationRule
{
private Func<bool> validation;
public ValidationRule(Func<bool> validation)
{
this.validation = validation;
}
public bool IsValid()
{
return validation();
}
}
would be more C# 3 style but is compiled to the same code as #Frank Krueger's answer.
This is what you asked for, but doesn't feel right. Is there a good reason why the entity can't be extended to perform validation?
Would a rule definition syntax like this one work for you?
public static void Valid(Address address, IScope scope)
{
scope.Validate(() => address.Street1, StringIs.Limited(10, 256));
scope.Validate(() => address.Street2, StringIs.Limited(256));
scope.Validate(() => address.Country, Is.NotDefault);
scope.Validate(() => address.Zip, StringIs.Limited(10));
switch (address.Country)
{
case Country.USA:
scope.Validate(() => address.Zip, StringIs.Limited(5, 10));
break;
case Country.France:
break;
case Country.Russia:
scope.Validate(() => address.Zip, StringIs.Limited(6, 6));
break;
default:
scope.Validate(() => address.Zip, StringIs.Limited(1, 64));
break;
}
Check out DDD and Rule driven UI Validation in .NET for more information

Categories

Resources