Hi I have the following code when I am adding values to a list.
var NoLiftingList = new List<SQLFields>();
SQLFields nolifting = new SQLFields();
nolifting.Field1 = "No lifting";
NoLiftingList.Add(nolifting);
SQLFields extremelifting = new SQLFields();
extremelifting.Field1 = "Up to 100 lbs (extreme lifting)";
NoLiftingList.Add(extremelifting);
How can I simplify this? Instead of initializing a new object all the time.
This is the code for the whole class updated below.
Thanks
You can add to a list, and set properties on a class by using this inline constructor syntax (working example):
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var NoLiftingList = new List<SQLFields>
{
new SQLFields
{
Field1 = "No Lifting"
},
new SQLFields
{
Field1 = "Up to 100lbs (extreme lifting)"
}
};
}
}
public class SQLFields
{
public string Field1 { get; set; }
}
Use Object Initializers with anonymous types
var NoLiftingList = new List<SQLFields>(){
new SQLFields() { Field1 = "No lifting"},
new SQLFields() { Field1 = "Up to 100 lbs (extreme lifting)"}
};
Ref: MSDN Link
Try this
var NoLiftingList = new List<SQLFields>()
{
new SQLFields()
{
Field1 = "No lifting"
},
new SQLFields()
{
Field1 = "Up to 100 lbs (extreme lifting)"
}
};
Related
The list needs to filter is having data like: '1000', '1000A', '1000B', '2000', '2000C', '2003', '2006A'
The list by which I am filtering having data like: '1000', '2000', '2003'
Expected output: 1000', '1000A', '1000B', '2000', '2000C', '2003'
(output is expected like we do in SQL server LIKE operator)
Suppose you are having two class like below,
public class MainClass
{
public string ActualValue { get; set; }
}
public class FilterClass
{
public string Description { get; set; }
}
I am loading some dummy data like this,
List<MainClass> mainList = new List<MainClass>();
mainList.Add(new MainClass() { ActualValue = "1000" });
mainList.Add(new MainClass() { ActualValue = "1000A" });
mainList.Add(new MainClass() { ActualValue = "1002F" });
mainList.Add(new MainClass() { ActualValue = "1002A" });
mainList.Add(new MainClass() { ActualValue = "1003" });
List<FilterClass> filterList = new List<FilterClass>();
filterList.Add(new FilterClass() { Description = "1003" });
filterList.Add(new FilterClass() { Description = "1002" });
The O/P will be given as per your requirement by,
var output1 = mainList.Where(x => filterList.Any(y => x.ActualValue.Contains(y.Description))).ToList();
Try with regex, like this:
var list1 = new List<string>{"1000", "1000A", "1000B","2000","2000A","3000BV"};
var list2 = new List<string>{"1000","2000"};
var result = list1.Where(x => list2.Any(y => Regex.IsMatch(x, $".*{y}.*"))).ToList();
Note: .* are the equivalent of % in SQL.
you could use linq in this way :
var filterList = new List<string>(){"1000", "1000A", "1000B", "2000", "2000C", "2003", "2006A"};
var filterLikeList = new List<string>(){"1000", "2000", "2003"};
var results = filterList.Where(x=> filterLikeList.Any(y=>x.Contains(y)));
I would like to pass an object and expression into a dynamically created workflow to mimic the Eval function found in many languages. Can anyone help me out with what I am doing wrong? The code below is a very simple example if taking in a Policy object, multiple its premium by 1.05, then return the result. It throws the exception:
Additional information: The following errors were encountered while processing the workflow tree:
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Value for a required activity argument 'To' was not supplied.
And the code:
using System.Activities;
using System.Activities.Statements;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Policy p = new Policy() { Premium = 100, Year = 2016 };
var inputPolicy = new InArgument<Policy>();
var theOutput = new OutArgument<object>();
Activity dynamicWorkflow = new DynamicActivity()
{
Properties =
{
new DynamicActivityProperty
{
Name="Policy",
Type=typeof(InArgument<Policy>),
Value=inputPolicy
}
},
Implementation = () => new Sequence()
{
Activities =
{
new Assign()
{
To = theOutput,
Value=new InArgument<string>() { Expression = "Policy.Premium * 1.05" }
}
}
}
};
WorkflowInvoker.Invoke(dynamicWorkflow);
}
}
public class Policy
{
public int Premium { get; set; }
public int Year { get; set; }
}
}
You can use Workflow Foundation to evaluate expressions, but it is far easier to use almost any other option.
The key issue at play with your code was that you were not trying to evaluate the expression (with either VisualBasicValue or CSharpValue). Assigning InArgument`1.Expression is an attempt to set the value - not to set the value to the result of an expression.
Keep in mind that compiling expressions is fairly slow (>10ms), but the resultant compiled expression can be cached for quick executions.
Using Workflow:
class Program
{
static void Main(string[] args)
{
// this is slow, only do this once per expression
var evaluator = new PolicyExpressionEvaluator("Policy.Premium * 1.05");
// this is fairly fast
var policy1 = new Policy() { Premium = 100, Year = 2016 };
var result1 = evaluator.Evaluate(policy1);
var policy2 = new Policy() { Premium = 150, Year = 2016 };
var result2 = evaluator.Evaluate(policy2);
Console.WriteLine($"Policy 1: {result1}, Policy 2: {result2}");
}
}
public class Policy
{
public double Premium, Year;
}
class PolicyExpressionEvaluator
{
const string
ParamName = "Policy",
ResultName = "result";
public PolicyExpressionEvaluator(string expression)
{
var paramVariable = new Variable<Policy>(ParamName);
var resultVariable = new Variable<double>(ResultName);
var daRoot = new DynamicActivity()
{
Name = "DemoExpressionActivity",
Properties =
{
new DynamicActivityProperty() { Name = ParamName, Type = typeof(InArgument<Policy>) },
new DynamicActivityProperty() { Name = ResultName, Type = typeof(OutArgument<double>) }
},
Implementation = () => new Assign<double>()
{
To = new ArgumentReference<double>() { ArgumentName = ResultName },
Value = new InArgument<double>(new CSharpValue<double>(expression))
}
};
CSharpExpressionTools.CompileExpressions(daRoot, typeof(Policy).Assembly);
this.Activity = daRoot;
}
public DynamicActivity Activity { get; }
public double Evaluate(Policy p)
{
var results = WorkflowInvoker.Invoke(this.Activity,
new Dictionary<string, object>() { { ParamName, p } });
return (double)results[ResultName];
}
}
internal static class CSharpExpressionTools
{
public static void CompileExpressions(DynamicActivity dynamicActivity, params Assembly[] references)
{
// See https://learn.microsoft.com/en-us/dotnet/framework/windows-workflow-foundation/csharp-expressions
string activityName = dynamicActivity.Name;
string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
{
Activity = dynamicActivity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = true
};
// add assembly references
TextExpression.SetReferencesForImplementation(dynamicActivity, references.Select(a => (AssemblyReference)a).ToList());
// Compile the C# expression.
var results = new TextExpressionCompiler(settings).Compile();
if (results.HasErrors)
{
throw new Exception("Compilation failed.");
}
// attach compilation result to live activity
var compiledExpression = (ICompiledExpressionRoot)Activator.CreateInstance(results.ResultType, new object[] { dynamicActivity });
CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation(dynamicActivity, compiledExpression);
}
}
Compare to the equivalent Roslyn code - most of which is fluff that is not really needed:
public class PolicyEvaluatorGlobals
{
public Policy Policy { get; }
public PolicyEvaluatorGlobals(Policy p)
{
this.Policy = p;
}
}
internal class PolicyExpressionEvaluator
{
private readonly ScriptRunner<double> EvaluateInternal;
public PolicyExpressionEvaluator(string expression)
{
var usings = new[]
{
"System",
"System.Collections.Generic",
"System.Linq",
"System.Threading.Tasks"
};
var references = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => !a.IsDynamic && !string.IsNullOrWhiteSpace(a.Location))
.ToArray();
var options = ScriptOptions.Default
.AddImports(usings)
.AddReferences(references);
this.EvaluateInternal = CSharpScript.Create<double>(expression, options, globalsType: typeof(PolicyEvaluatorGlobals))
.CreateDelegate();
}
internal double Evaluate(Policy policy)
{
return EvaluateInternal(new PolicyEvaluatorGlobals(policy)).Result;
}
}
Roslyn is fully documented, and has the helpful Scripting API Samples page with examples.
I have a set of nested classes from datasource (VSO) and I would like to mapped to contracts. The point of mapping is the next:
the mapped object (contract) will have a new property, called AreaPathFull, which will have the concatenated AreaPath values of all nodes above it in the tree.
Why I want this?:
it is for displaying purposes on UI
it can be solved on UI side by dealing with javascript is pain in the bottom for me, C# much easier, might not be the best idea ever, but still...
Question:
it is possible to achieve this by using Automapper?
Unfortunately, I have almost nothing experience with Automapper and if it is not possible then I would not like to spend my time with it. If so, then I think, CustomValueResolve will be my friend.
Source:
public class Class1ToBeMapped
{
public string AreaPath = "Level1";
public List<Class1ToBeMapped> Children = new List<Class1ToBeMapped>()
{
{new Class1ToBeMapped()
{
AreaPath = "Level21",
Children = new List<Class1ToBeMapped>(){}
}},
{new Class1ToBeMapped()
{
AreaPath = "Level22",
Children = new List<Class1ToBeMapped>(){}
}}
};
}
Mapped object, desired result:
public class Class2Mapped
{
public string AreaPath = "Level1";
public string AreaPathFull = "Level1";
public List<Class2Mapped> Children = new List<Class2Mapped>()
{
{
new Class2Mapped()
{
AreaPath = "Level21",
AreaPathFull = "Level1/Level21",
Children = new List<Class2Mapped>()
{
{
new Class2Mapped()
{
AreaPath = "Level31",
AreaPathFull = "Level1/Level21/Level31",
Children = new List<Class2Mapped>()
{
{
new Class2Mapped()
{
AreaPath = "Level41",
AreaPathFull = "Level1/Level21/Level31/Level41",
Children = null
}
}
}
}
},
{
new Class2Mapped()
{
AreaPath = "Level22",
AreaPathFull = "Level1/Level22",
Children = new List<Class2Mapped>()
{
new Class2Mapped()
{
AreaPath = "Level32",
AreaPathFull = "Level1/Level22/Level32",
Children = null
}
}
}
}
}
},
}
};
}
I used to compare lists like this, but it returns false in a test:
Assert.IsTrue(expected.SequenceEquals(actual));
And tried converting to json and it worked:
Assert.AreEqual(expected.ToJson(), actual.ToJson());
Values seems to be equal, what could be different? How to find out what is different in the lists?
Updated:
My class:
public class Department
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Id.ToString();
}
}
If MyClass implements IEquatable<MyClass>, then try this:
expected.Sort();
actual.Sort();
if (Enumerable.SequenceEqual(actual, expected)) { ... }
If it does not implement IEquatable then you could expect strange behavior, since the object references will be compared in the two lists, and not their fields:
using System;
using System.Collections.Generic;
using System.Linq;
public class MyClassA
{
private int i;
public MyClassA(int i) { this.i = i; }
}
public class MyClassB : IEquatable<MyClassB>
{
private int i;
public MyClassB(int i) { this.i = i; }
public bool Equals(MyClassB other) { return this.i == other.i; }
}
public class Program
{
public static void Main()
{
var actual1 = new List<MyClassA>() { new MyClassA(1), new MyClassA(2), new MyClassA(3) };
var expected1 = new List<MyClassA>() { new MyClassA(1), new MyClassA(2), new MyClassA(3) };
Console.WriteLine(Enumerable.SequenceEqual(actual1, expected1));
var a1 = new MyClassA(1);
var a2 = new MyClassA(2);
var a3 = new MyClassA(3);
var actual2 = new List<MyClassA>() { a1, a2, a3 };
var expected2 = new List<MyClassA>() { a1, a2, a3 };
Console.WriteLine(Enumerable.SequenceEqual(actual2, expected2));
var actual3 = new List<MyClassB>() { new MyClassB(1), new MyClassB(2), new MyClassB(3) };
var expected3 = new List<MyClassB>() { new MyClassB(1), new MyClassB(2), new MyClassB(3) };
Console.WriteLine(Enumerable.SequenceEqual(actual3, expected3));
var actual4 = new List<MyClassB>() { new MyClassB(1), new MyClassB(2), new MyClassB(3) };
var expected4 = new List<MyClassB>() { new MyClassB(3), new MyClassB(2), new MyClassB(1) };
Console.WriteLine(Enumerable.SequenceEqual(actual4, expected4));
}
}
Output:
False
True
True
False
using System.Linq;
Enumerable.SequenceEqual(a, b);
// or SequenceEqual(a, b, StringComparer.OrdinalIgnoreCase)
See MSDN, also this question.
Perhaps you can use IEnumerable.ExceptOf
http://msdn.microsoft.com/en-us/library/bb300779.aspx
Our perhaps you can use an HashSet and there the intersect method.
http://msdn.microsoft.com/en-us/library/bb293080.aspx
I tend to find the HashSet<T> collection fit for this kind of purpose, cast your collections into HashSet<T> then call SetEquals
I have an Interface [BindControls] which takes data from GUI and store it into a list „ieis”.
After that, Into another class, which sends this data through WebServices, I want to take this data from „ieis” and put it into required by WS Class fields (bottom is a snippet of code)
This is the interface:
void BindControls(ValidationFrameBindModel<A.B> model)
{
model.Bind(this.mtbxTax, (obj, value) =>
{
var taxa = TConvertor.Convert<double>((string)value, -1);
if (taxa > 0)
{
var ieis = new List<X>();
var iei = new X
{
service = new ServiceInfo
{
id = Constants.SERVICE_TAX
},
amount = tax,
currency = new CurrencyInfo
{
id = Constants.DEFAULT_CURRENCY_ID
}
};
ieis.Add(iei);
}
},"Tax");
}
This is the intermediate property:
//**********
class A
{
public B BasicInfo
{
get;
set;
}
class B
{
public X Tax
{
get;
set;
}
}
}
//***********
This is the class which sends through WS:
void WebServiceExecute(SomeType someParam)
{
//into ‚iai’ i store the data which comes from interface
var iai = base.Params.FetchOrDefault<A>( INFO, null);
var convertedObj = new IWEI();
//...
var lx = new List<X>();
//1st WAY: I tried to put all data from ‚Tax’into my local list ‚lx’
//lx.Add(iai.BasicInfo.Tax); - this way is not working
//2nd WAY: I tried to put data separately into ‚lx’
var iei = new X
{
service = new ServiceInfo
{
id = iai.BasicInfo.Tax.service.id
},
amount = iai.BasicInfo.Tax.amount,
currency = new CurrencyInfo
{
id = iai.BasicInfo.Tax.currency.id
}
};
lx.Add(iei);
// but also is not working
Can you help me please to suggest how to implement a way that will fine do the work (take data from ‚ieis’ and put her into ‚lx’).
Thank you so much
As noted in my comment, it looks like iai.BasicInfo.Tax is null, once you find out why that is null your original Add() (#1) will work.