Today I created a factory for operator based Expression.
But when I create my factory, it has some dependency on comparison value.
Here is my code
public LambdaExpression GetPredicate(FieldType fieldType, GigFilterOption value)
{
switch (fieldType)
{
case FieldType.PriceNumeric :
return new OperatorFactory( Convert.ToDecimal(value.LowerLimit), Convert.ToDecimal(value.UpperLimit)).GetOperator((Operator)value.Operator).Apply<YayNinja.DAL.Task>("Price");
break;
case FieldType.TimePeriod :
return new OperatorFactory(Convert.ToDecimal(value.LowerLimit), Convert.ToDecimal(value.UpperLimit)).GetOperator((Operator)value.Operator).Apply<YayNinja.DAL.Task>("Duration");
break;
case FieldType.CheckBox:
case FieldType.Radio:
return new OperatorFactory(value.LowerLimit, value.UpperLimit).GetOperator((Operator)value.Operator).Apply<TaskField>("Value");
break;
default :
throw new NotImplementedException();
};
}
Here is My Operator factory.
public class OperatorFactory : IOperatoFactory
{
private object lowerLimit;
private object upperLimit;
public OperatorFactory(object _lowerLimit, object _upperLimit) //**here you see dependency of value that i need for comparsion.**
{
lowerLimit = _lowerLimit;
upperLimit = _upperLimit;
}
public IOperatorPredicate GetOperator(Operator #operator)
{
IOperatorPredicate operatorPredicate = null;
switch (#operator)
{
case Operator.Equal:
operatorPredicate = new EqualToPredicate(lowerLimit);
break;
case Operator.GreaterThan:
operatorPredicate = new GreaterThanPredicate(lowerLimit);
break;
case Operator.GreaterThanOrEqual:
operatorPredicate = new GreaterThanEqualPerdicate(lowerLimit);
break;
case Operator.LessThan:
operatorPredicate = new LessThanPredicate(lowerLimit);
break;
case Operator.LessThanOrEqual:
operatorPredicate = new LessThanEqualPredicate(lowerLimit);
break;
case Operator.Between:
operatorPredicate = new BetweenPredicate(lowerLimit,upperLimit);
break;
default:
throw new NotImplementedException();
}
return operatorPredicate;
}
}
I m sure that factory pattern is creator pattern it only create object without any dependency.
Please guide me on this topic
Related
I have the following json string:
[
{
"Key":"A",
"Value":null
},
{
"Key":"B",
"Value":"18"
},
{
"Key":"C",
"Value":"False"
},
{
"Key":"D",
"Value":"BOB"
}
]
I would like to be able to deserialize into the following objects:
public class ModelOne
{
public int? A { get; set; }
public int B { get; set;}
}
public class ModelTwo
{
public bool C { get; set; }
public string D { get; set; }
}
We thought about using var model = JsonConvert.DeserializeObject<ModelOne>(json); but clearly the json string is a list of Key and Value so that wouldn't work.
In an ideal world we would like to parse the json and match the Key to the Property Name and set the Value according to the property type. We could use a similar function to the above which accepts an anonymous type we're just not sure where to start so would be very greatful for some feedback and or assistance.
Thanks in advance.
EDIT:
The json array represents some data points we receive from an external api call.
ModelOne and ModelTwo are each view models in our MVC project we would like to pre-populate.
Thanks very much for all of your comments but notably both of #mjwills and #Heretic Monkey you really helped.
In the (end against my better judgement) I decided to use a little reflection.
public T ConvertDataMapToModel<T>(T item, List<Data> list)
{
Type itemType = typeof(T);
var response = (T)item;
var props = response.GetType().GetProperties();
foreach (var prop in props)
{
string propName = prop.Name;
string listValue = (string)(from c in list where c.Key == prop.Name select c.Value).FirstOrDefault();
if (!string.IsNullOrWhiteSpace(listValue) && !string.IsNullOrEmpty(listValue))
{
PropertyInfo pInstance = itemType.GetProperty(propName);
Type pInstancePropertyType = pInstance.PropertyType;
if (pInstancePropertyType.IsGenericType && pInstancePropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
pInstancePropertyType = pInstancePropertyType.GetGenericArguments()[0];
}
TypeCode typeCode = Type.GetTypeCode(pInstancePropertyType);
switch (typeCode)
{
case TypeCode.Boolean:
pInstance.SetValue(response, Convert.ToBoolean(listValue));
break;
case TypeCode.Byte:
pInstance.SetValue(response, Convert.ToByte(listValue));
break;
case TypeCode.Char:
pInstance.SetValue(response, Convert.ToChar(listValue));
break;
case TypeCode.DateTime:
pInstance.SetValue(response, Convert.ToDateTime(listValue));
break;
case TypeCode.DBNull:
pInstance.SetValue(response, Convert.DBNull);
break;
case TypeCode.Decimal:
pInstance.SetValue(response, Convert.ToDecimal(listValue));
break;
case TypeCode.Double:
pInstance.SetValue(response, Convert.ToDouble(listValue));
break;
case TypeCode.Empty:
pInstance.SetValue(response, "");
break;
case TypeCode.Int16:
pInstance.SetValue(response, Convert.ToInt16(listValue));
break;
case TypeCode.Int32:
pInstance.SetValue(response, Convert.ToInt32(listValue));
break;
case TypeCode.Int64:
pInstance.SetValue(response, Convert.ToInt64(listValue));
break;
case TypeCode.SByte:
pInstance.SetValue(response, Convert.ToSByte(listValue));
break;
case TypeCode.Single:
pInstance.SetValue(response, Convert.ToSingle(listValue));
break;
case TypeCode.String:
pInstance.SetValue(response, Convert.ToString(listValue));
break;
case TypeCode.UInt16:
pInstance.SetValue(response, Convert.ToUInt16(listValue));
break;
case TypeCode.UInt32:
pInstance.SetValue(response, Convert.ToUInt32(listValue));
break;
case TypeCode.UInt64:
pInstance.SetValue(response, Convert.ToUInt64(listValue));
break;
}
}
}
return response;
}
I have started to use C# 7's type based pattern matching. A method that only manages a single pattern-based result looks very clean and is easy to reason about.
However, once a second pattern-based result that depends on the first pattern-based result creates an arrow anti-pattern, and will only get worse with n-results that depend on each other.
Here is an simplified example that demonstrates the arrow pattern:
public Result<bool> ValidateSomething(string strId)
{
var id = Guid.Parse(strId);
Result<Something> fetchSomethingResult = new SomethingDao.FetchSomething(id);
switch (fetchSomethingResult)
{
case ValueResult<Something> successfulSomethingResult:
Result<Related> fetchRelatedFieldsResult = new RelatedDao.FetchRelatedFields(successfulSomethingResult.Value.RelatedId);
switch (fetchRelatedFieldsResult)
{
case ValueResult<Related> successfulFieldValueResult:
var isValid = successfulSomethingResult.Value.ComparableVal <= successfulFieldValueResult.Value.RelatedComparableVal;
return new ValueResult<bool>(isValid);
case ValueNotFoundResult<Related> _:
return new ValueNotFoundResult<bool>();
case ErrorResult<Related> errorResult:
return new ErrorResult<bool>(errorResult.ResultException);
default:
throw new NotImplementedException("Unexpected Result Type Received.");
}
case ValueNotFoundResult<Something> notFoundResult:
return new ValueNotFoundResult<bool>();
case ErrorResult<Something> errorResult:
return new ErrorResult<bool>(errorResult.ResultException);
default:
throw new NotImplementedException("Unexpected Result Type Received.");
}
}
For reference, these are the definitions for the Result classes:
public abstract class Result<T>
{
}
public class ValueResult<T> : Result<T>
{
public ValueResult()
{
}
public ValueResult(T inValue)
{
Value = inValue;
}
public T Value { get; set; }
}
public class ValueNotFoundResult<T> : Result<T>
{
public ValueNotFoundResult()
{
}
}
public class ErrorResult<T> : Result<T>
{
public Exception ResultException { get; set; }
public ErrorResult()
{
}
public ErrorResult(Exception resultException)
{
ResultException = resultException;
}
}
What options are there to handle this type of code better? What suggestions do you have for the previous examples? How do I avoid the arrow anti-pattern with pattern-based results?
Since you are only really doing anything with the result in case it was successfull, it seem fairly simple to move the switch to an extension method. You might need two extensions, depending on if the function return a new result or just T, something like :
public static Result<TOut> SelectValue<TIn, TOut>(this Result<TIn> self, Func<TIn, Result<TOut>> select)
{
switch (self)
{
case ErrorResult<TIn> errorResult: return new ErrorResult<TOut>(errorResult.ResultException);
case ValueNotFoundResult<TIn> valueNotFoundResult: return new ValueNotFoundResult<TOut>();
case ValueResult<TIn> valueResult: return select(valueResult.Value);
default: throw new ArgumentOutOfRangeException(nameof(self));
}
}
public static Result<TOut> SelectValue<TIn, TOut>(this Result<TIn> self, Func<TIn, TOut> select)
{
switch (self)
{
case ErrorResult<TIn> errorResult: return new ErrorResult<TOut>(errorResult.ResultException);
case ValueNotFoundResult<TIn> valueNotFoundResult: return new ValueNotFoundResult<TOut>();
case ValueResult<TIn> valueResult: return new ValueResult<TOut>(select(valueResult.Value));
default: throw new ArgumentOutOfRangeException(nameof(self));
}
}
You can then handle the success-cases like this:
var result = fetchSomethingResult
.SelectValue(something => new RelatedDao.FetchRelatedFields(something.RelatedId))
.SelectValue(related => related.CompareVal >= 5);
If you need to use values from both "Something" and "Related" you will unfortunately need to nest calls.
var result = fetchSomethingResult
.SelectValue(something => new RelatedDao.FetchRelatedFields(something.RelatedId).SelectValue(related => related.CompareVal >= 5));
I am currently building a class library to handle unit measurements and I wanted to use the factory pattern with static methods to create lengths or areas and so on.
To keep the methods consistent I wanted to create an interface or a superclass. Is there a possible way to enforce subclasses to implement a static method?
(Offtopic: Is it also possible to enforce subclasses to overload operators?)
For example:
public class Length
{...
public static Length Create(double value, string unitCode)
{
var length = new Length();
switch (unitCode)
{
case "Mm":
length.Megameters = value;
break;
case "Km":
case "km":
length.Kilometers = value;
break;
case "hm":
length.Hectometers = value;
break;
case "dam":
length.Decameters = value;
break;
case "m":
length.Meters = value;
break;
case "dm":
length.Decimeters = value;
break;
case "cm":
length.Centimeters = value;
break;
case "mm":
length.Millimeters = value;
break;
case "µm":
length.Micrometers = value;
break;
case "pm":
length.Picometers = value;
break;
case "in":
length.Inches = value;
break;
case "ft":
length.Feet = value;
break;
case "yd":
length.Yards = value;
break;
case "mi":
length.Miles = value;
break;
case "smi":
length.ScandinavianMiles = value;
break;
case "ly":
length.LightYears = value;
break;
case "NM":
length.NauticalMiles = value;
break;
case "ftm":
length.Fathoms = value;
break;
case "fur":
length.Furlongs = value;
break;
case "ua":
length.AstronomicalUnits = value;
break;
case "pc":
length.Parsecs = value;
break;
default:
throw new ArgumentException("Not a valid unit given.", nameof(unitCode));
}
return length;
}
... }
I am trying to create a new variable based on a particular value received from a function.
The variable can be of different classes.
Here's what I am trying:
switch (request)
{
case "ClassA":
{
var x = new ClassA();
break;
}
case "ClassB":
{
var x = new ClassB();
break;
}
case "ClassC":
{
var x = new ClassC();
break;
}
case "ClassD":
{
var x = new ClassD();
break;
}
default:
break;
}
This is fine till here and no issues. The issue arises, when I try to use the value of x out of the scope of the switch statement. The system says that x does not exists in the current context.
Is there any way to achieve this?
You must declare x outside switch. and declare it only once. and if classes does not have same parent you must use dynamic as a type of x.
ParentClass x = null;// dynamic x = null; in case that x is not known type
switch (request)
{
case "ClassA":
{
x = new ClassA();
break;
}
case "ClassB":
{
x = new ClassB();
break;
}
case "ClassC":
{
x = new ClassC();
break;
}
case "ClassD":
{
x = new ClassD();
break;
}
default:
break;
}
This looks like a good place for an interface or abstract class.
Basically, to most easily solve your issue, you would implement an interface as follows:
interface IDescriptiveName
{
DescriptiveNameType Type { get; }
}
enum DescriptiveNameType
{
ClassA
}
Each class would then implement DescriptiveNameType Type and return their type. (Generally DescriptiveNameType is an enum.) I.e.
public class ClassA : IDescriptiveName
{
public DescriptiveNameType Type { get { return DescriptiveNameType.ClassA; } }
}
Then, based on the value of ClassA.Type (which for ClassA would be ClassA) you could cast x and work with it.
IDescriptiveName x = null;
// original switch logic simply remove var
if (x.Type == DescriptiveNameType.ClassA)
{
// do something for ClassA
}
Rather than use a switch statement, use a Dictionary to provide the class lookup:
private readonly Dictionary<string, Func<object>> classLookup =
new Dictionary<string, Func<object>>
{
{ "ClassA", () => new ClassA() },
{ "ClassB", () => new ClassB() },
{ "ClassC", () => new ClassC() },
{ "ClassD", () => new ClassD() }
};
public object GetObject(string className)
{
return classLookup.ContainsKey(className)
? classLookup[className]()
: null;
}
How will a C# switch statement's default label handle a nullable enum?
Will the default label catch nulls and any unhandled cases?
If it's null, it will hit the default label.
public enum YesNo
{
Yes,
No,
}
public class Program
{
public static void Main(string[] args)
{
YesNo? value = null;
switch (value)
{
case YesNo.Yes:
Console.WriteLine("Yes");
break;
case YesNo.No:
Console.WriteLine("No");
break;
default:
Console.WriteLine("default");
break;
}
}
}
The program will print default.
Unless null is handled.
public class Program
{
public static void Main(string[] args)
{
YesNo? value = null;
switch (value)
{
case YesNo.Yes:
Console.WriteLine("Yes");
break;
case YesNo.No:
Console.WriteLine("No");
break;
case null:
Console.WriteLine("NULL");
break;
default:
Console.WriteLine("default");
break;
}
}
}
prints NULL.
If you have an unhandled enum value that was added later:
public enum YesNo
{
Yes,
No,
FileNotFound,
}
public class Program
{
public static void Main(string[] args)
{
YesNo? value = YesNo.FileNotFound;
switch (value)
{
case YesNo.Yes:
Console.WriteLine("Yes");
break;
case YesNo.No:
Console.WriteLine("No");
break;
default:
Console.WriteLine("default");
break;
}
}
}
It still prints default.
You can use the null-coalescing operator ?? to route null switch values to a specific case label other than default:
public static IEnumerable<String> AsStrings(this IEnumerable<Char[]> src)
{
Char[] rgch;
var e = src.GetEnumerator();
while (e.MoveNext())
{
switch ((rgch = e.Current)?.Length ?? -1)
{
case -1: // <-- value when e.Current is 'null'
yield return null;
break;
case 0:
yield return String.Empty;
break;
case 1:
yield return String.Intern(new String(rgch[0], 1));
break;
default: // 2...n
yield return new String(rgch);
break;
}
}
}
You can have a case for null.
switch (MyNullableEnum)
{
case Option1:
break;
case Option2:
break;
case Option3:
break;
case null:
break;
default:
break;
}
It's worth to mention that C# 8.0 introduced a new Property Pattern for a switch expression. Now you can implement default logic to switch by using underscore:
public double Calculate(int left, int right, Operator op) =>
op switch
{
Operator.PLUS => left + right,
Operator.MINUS => left - right,
Operator.MULTIPLY => left * right,
Operator.DIVIDE => left / right,
_ => 0 // default
}
Ref. https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8