I read DataTable are of Reference type, then does using ref keyword make any difference ? Are below two approaches same in terms of performance?
(1)
public int CalculateValues(DataTable dt)
{
int output = 0;
foreach(DataRow row in dt.Rows)
{
//CalculateValues
}
return output;
}
(2)
public int CalculateValues(ref DataTable dt)
{
int output = 0;
foreach(DataRow row in dt.Rows)
{
//CalculateValues
}
return output;
}
(1) vs (2) ?
When you pass value type to method, it's do copy your variable, but when you pass reference type it's copy pointer value.
Here is example.
public void Change(ReferenceType val)
{
val = new ReferenceType();
}
public void ChangeRef(ref ReferenceType val)
{
val = new ReferenceType();
}
void SomeFunction()
{
var variable = new ReferenceType();
var tmp = variable;
Change(variable); // variable not changed
Console.WriteLine(variable == tmp); // will print TRUE
ChangeRef(ref variable); // variable changed
Console.WriteLine(variable == tmp); // will print FALSE
}
So, it's not about performance at all.
Related
I would like to evaluate a CSV data series with Xunit.
For this I need to read in a string consisting of int, bool, double and others.
With the following code, the transfer basically works for one row.
But since I want to test for predecessor values, I need a whole CSV file for evaluation.
My [Theory] works with InlineData without errors.
But when I read in a CSV file, the CSVDataHandler gives a System.ArgumentOutOfRangeException!
I can't find a solution for the error and ask for support.
Thanks a lot!
[Theory, CSVDataHandler(false, "C:\\MyTestData.txt", Skip = "")]
public void TestData(int[] newLine, int[] GetInt, bool[] GetBool)
{
for (int i = 0; i < newLine.Length; i++)
{
output.WriteLine("newLine {0}", newLine[i]);
output.WriteLine("GetInt {0}", GetInt[i]);
output.WriteLine("GetBool {0}", GetBool[i]);
}
}
[DataDiscoverer("Xunit.Sdk.DataDiscoverer", "xunit.core")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public abstract class DataArribute : Attribute
{
public abstract IEnumerable<object> GetData(MethodInfo methodInfo);
public virtual string? Skip { get; set; }
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class CSVDataHandler : DataAttribute
{
public CSVDataHandler(bool hasHeaders, string pathCSV)
{
this.hasHeaders = hasHeaders;
this.pathCSV = pathCSV;
}
public override IEnumerable<object[]> GetData(MethodInfo methodInfo)
{
var methodParameters = methodInfo.GetParameters();
var paramterTypes = methodParameters.Select(p => p.ParameterType).ToArray();
using (var streamReader = new StreamReader(pathCSV))
{
if (hasHeaders) { streamReader.ReadLine(); }
string csvLine = string.Empty;
// ReadLine ++
//while ((csvLine = streamReader.ReadLine()) != null)
//{
// var csvRow = csvLine.Split(',');
// yield return ConvertCsv((object[])csvRow, paramterTypes);
//}
// ReadToEnd ??
while ((csvLine = streamReader.ReadToEnd()) != null)
{
if (Environment.NewLine != null)
{
var csvRow = csvLine.Split(',');
yield return ConvertCsv((object[])csvRow, paramterTypes); // System.ArgumentOutOfRangeException
}
}
}
}
private static object[] ConvertCsv(IReadOnlyList<object> cswRow, IReadOnlyList<Type> parameterTypes)
{
var convertedObject = new object[parameterTypes.Count];
for (int i = 0; i < parameterTypes.Count; i++)
{
convertedObject[i] = (parameterTypes[i] == typeof(int)) ? Convert.ToInt32(cswRow[i]) : cswRow[i]; // System.ArgumentOutOfRangeException
convertedObject[i] = (parameterTypes[i] == typeof(double)) ? Convert.ToDouble(cswRow[i]) : cswRow[i];
convertedObject[i] = (parameterTypes[i] == typeof(bool)) ? Convert.ToBoolean(cswRow[i]) : cswRow[i];
}
return convertedObject;
}
}
MyTestData.txt
1,2,true,
2,3,false,
3,10,true,
The first call to streamReader.ReadToEnd() will return the entire contents of the file in a string, not just one line. When you call csvLine.Split(',') you will get an array of 12 elements.
The second call to streamReader.ReadToEnd() will not return null as your while statement appears to expect, but an empty string. See the docu at
https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoend?view=net-7.0
If the current position is at the end of the stream, returns an empty
string ("").
With the empty string, the call to call csvLine.Split(',') will return an array of length 0, which causes your exception when its first element (index 0) is accessed.
All of this could have been easily discovered by simply starting the test in a debugger.
It looks like you have some other issues here as well.
I don't understand what your if (Environment.NewLine != null) is intended to do, the NewLine property will never be null but should have one of the values "\r\n" or "\n" so the if will always be taken.
The parameters of your test method are arrays int[] and bool[], but you are checking against the types int, double and bool in your ConvertCsv method, so the alternative cswRow[i] will always be returned. You'll wind up passing strings to your method expecting int[] and bool[] and will at latest get an error there.
This method reads a data series from several rows and columns and returns it as an array for testing purposes.
The conversion of the columns can be adjusted according to existing pattern.
Thanks to Christopher!
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class CSVDataHandler : Xunit.Sdk.DataAttribute
{
public CSVDataHandler(string pathCSV)
{
this.pathCSV = pathCSV;
}
public override IEnumerable<object[]> GetData(MethodInfo methodInfo)
{
List<int> newLine = new();
List<int> GetInt = new();
List<bool> GetBool = new();
var reader = new StreamReader(pathCSV);
string readData = string.Empty;
while ((readData = reader.ReadLine()) != null)
{
string[] split = readData.Split(new char[] { ',' });
newLine.Add(int.Parse(split[0]));
GetInt.Add(int.Parse(split[1]));
GetBool.Add(bool.Parse(split[2]));
// Add more objects ...
}
yield return new object[] { newLine.ToArray(), GetInt.ToArray(), GetBool.ToArray() };
}
}
I am trying to append float values that the user inputs through the serial monitor. I need these values stored in an array in a sequential fashion, i.e. each time I get a value, I must append it to the array.
Arduino doesn't come out of the box with dynamic data structures (except for String).
You can download open source implementations of generic containers from the web. Here's one: https://github.com/dhbikoff/Generic-C-Library/blob/master/vector.h
Also, here's a simple linked-list/vector I implemented myself as a toy project.
Be careful with dynamic memory. Memory fragmentation can cause your sketch to crash randomly (has happened to me several times).
template <typename T>
struct SimpleVector {
struct SimpleVectorNode {
T* m_value = NULL;
SimpleVectorNode* m_next = NULL;
SimpleVectorNode() {
}
SimpleVectorNode(T val) {
m_value = new T(val);
m_next = NULL;
}
};
int m_size = 0;
SimpleVectorNode* m_head = new SimpleVectorNode;
void AddValue(T val) {
++m_size;
SimpleVectorNode* end = m_head;
while (end->m_next != NULL) {
end = end->m_next;
}
end->m_next = new SimpleVectorNode(val);
}
SimpleVectorNode* Seek(int index) {
SimpleVectorNode* res = m_head;
while (index >= 0) {
--index;
res = res->m_next;
}
return res;
}
T& Get(int index) {
return *(Seek(index)->m_value);
}
void Delete(int index) {
SimpleVectorNode* preDel = Seek(index - 1);
SimpleVectorNode* toDel = preDel->m_next;
preDel->m_next = toDel->m_next;
delete toDel->m_value;
delete toDel;
--m_size;
}
int GetSize() {
return m_size;
}
int IndexOf(T val) {
SimpleVectorNode* pNode = m_head->m_next;
for (int i = 0; i < m_size; ++i) {
if (pNode->m_value == val) {
return i;
}
pNode = pNode->m_next;
}
return -1;
}
bool Contains(T val) {
return IndexOf(val) >= 0;
}
~SimpleVector() {
while (m_size > 0) {
Delete(0);
}
delete m_head;
}
};
we have string example :
www.example.com/default.aspx?code-1/price-2/code-4/
i want to get integers from code and price and save to list of integers.
for example , 1 and 4 are codes , 2 is price for filter in site.
InBetween = GetStringInBetween("Brand-", "/", Example, false, false);
please help me.
Below is a simple program that completes your requirement.
class Program
{
public void GetCodesAndPrice(string url,out List<int> listOfCodes, out List<int> listOfPrice )
{
listOfCodes=new List<int>();
listOfPrice = new List<int>();
url = url.Substring(url.IndexOf('?')+1);
var strArray = url.Split('/');
foreach (string s in strArray)
{
if(s.ToLower().Contains("code"))
listOfCodes.Add(GetIntValue(s));
else if(s.ToLower().Contains("price"))
listOfPrice.Add(GetIntValue(s));
}
// Now you have list of price in "listOfPrice" and codes in "listOfCodes",
// If you want to return these two list then declare as out
}
public int GetIntValue(string str)
{
try
{
return Convert.ToInt32(str.Substring(str.IndexOf('-') + 1));
}
catch (Exception ex)
{
// Handle your exception over here
}
return 0; // It depends on you what do you want to return if exception occurs in this function
}
public static void Main()
{
var prog = new Program();
List<int> listOfCodes;
List<int> listOfPrice;
prog.GetCodesAndPrice("www.example.com/default.aspx?code-1/price-2/code-4/", out listOfCodes,out listOfPrice);
Console.ReadKey();
}
}
It is complete console program. Test it and Embed in your program. Hope this will help you
I need a function that can give me all possible combinations of a array back.
Example:
$source = array('a', 'b', 'c');
$target = thisiswhatisearch($source);
Now the $target should look like:
array('a','b','c','ab','ac','cb','abc')
I dont need the aa, bb, cc.
I also dont need the the ba, ca, acb.. because the order isn't important to me.
Thanks for any help.
Tried to be language agnostic but i guess its C like:
function combinations(array arr)
{
combos = array();
for (int i=1; i<2**arr.size(); i++)
{
int x = i;
int c = 0;
str = "";
while(x>0)
{
int rem = x % 2;
if(rem == 1)
str += arr[c];
x = x / 2;
c++;
}
combos.add(str);
}
return combos;
}
The Wikipedia entry for Combination has a link to C code that does this.
That's an out of the mind solution. It is probably not the fastest and cleanest one, but it kind of works. It's in Java, because I had it open:
public class Combination {
public static void main(String[] args) {
String[] source = {"a","b","c"};
List<String> result = combineMe(new ArrayList<String>(Arrays.asList(source)));
for (String string : result) {
System.out.println(string);
}
}
public static List<String> combineMe(List<String> source) {
List<String> result = new ArrayList<String>();
if (source.size()==0) {
result.add("");
return result;
}else{
String tmp = source.remove(0);
source = combineMe(source);
for (String string : source) {
result.add(("" + string).trim());
result.add(tmp + string);
}
}
return result;
}
}
The first entry in the resulting list is a fake one, and needs to be removed at the end
I have written this class-methods for .net 2.0 to create objects from '|'-separated strings and vise-versa.
But the problem is, they are not giving right results in case of Inherted types, i.e. inherited properties are coming last and the sequence of the data supplied in the form of a '|'-separated string is not working.
For example:
class A
{
int ID;
}
class B : A
{
string Name;
}
the string is "1|John". the methods are reading as the name==1 and ID=="John".
Please tell me how to do it.
public class ObjectConverter<T>
{
public static T TextToObject(string text)
{
T obj = Activator.CreateInstance<T>();
string[] data = text.Split('|');
PropertyInfo[] props = typeof(T).GetProperties();
int objectPropertiesLength = props.Length;
int i = 0;
if (data.Length == objectPropertiesLength)
{
for (i = 0; i < objectPropertiesLength; i++)
{
props[i].SetValue(obj, data[i], null);
}
}
return obj;
}
public static string ObjectToText(T obj)
{
StringBuilder sb = new StringBuilder();
Type t = typeof(T);
PropertyInfo[] props = t.GetProperties();
int i = 0;
foreach (PropertyInfo pi in props)
{
object obj2 = props[i++].GetValue(obj, null);
sb.Append(obj2.ToString() + "|");
}
sb = sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
}
I don't think the runtime assures you that when you call getproperties the property info objects will always be in the same order. You will need to do something like get the list of property names sort them and use the same sorting for serialization and deserialization .
There are at least 3 ways to serialize object built into .net is there a reason why you are not using one of those