Can someone show me a simple way to assign variables.
I have many variables and not really know how to do, whether it be possible to use a loop?`
public void SwappingPlaces1()
{
Section_1[0] = Receiver_1[0];
Section_1[1] = Receiver_2[0];
Section_1[2] = Receiver_3[0];
Section_1[3] = Receiver_4[0];
Section_1[4] = Receiver_5[0];
Section_1[5] = Receiver_6[0];
Section_1[6] = Receiver_7[0];
Section_1[7] = Receiver_8[0];
Section_1[8] = Receiver_9[0];
Section_1[9] = Receiver_10[0];
Section_1[10] = Receiver_11[0];
Section_1[11] = Receiver_12[0];
Section_1[12] = Receiver_13[0];
Section_1[13] = Receiver_14[0];
Section_1[14] = Receiver_15[0];
Section_1[15] = Receiver_16[0];
Section_1[16] = Receiver_17[0];
Section_1[17] = Receiver_18[0];
Section_1[18] = Receiver_19[0];
Section_1[19] = Receiver_20[0];
Section_1[n] = Receiver_n[0];
...
}
You need to use reflection to get the names of the properties/fields by their name. Assuming Reciever_n is a property:
var properties = this.GetType().GetProperties();
for(int i = 0; i < n; i++)
{
var p = properties.Single(x => x.Name == "Receiver_" + i);
var value = p.GetValue(this, new object[] { 0 });
}
First you get all the properties defined on the type. Now you loop your list and get that single property with the name Receiver_ plus the current index.
Finally you invoke that property on the instance and provide the index of the indexed property (which is equal to zero here).
EDIT: However having so many properties with equal name and type seems a design-flaw, you should consider your actual design.
Thus a better appraoch might be to have just one single two-dimensional array Receiver.
You could add reference variables to an array and iterate over them. This is mostly usefull, clearing gui controls, like textboxes/labels etc.
var variables = new[] { Receiver_1, Receiver_2, Receiver_3, Receiver_4,
Receiver_5, Receiver_6 };
for(int i=0; i<Section_1.Length;i++)
Section_1[i] = variables[i][0];
But an index out of bounds is easely created
You could also use reflection.
Related
I want to display a hashset with all the different values between two DataGridView, but I have not been successful in displaying the strings, I attach images.
var dataA = new HashSet<string>();
var dataB = new HashSet<string>();
for (int i = 1; i < dgv_A.Rows.Count; i++)
{
dataA.Add(dgv_A[8, i].Value.ToString());
}
for (int i = 1; i < dgv_B.Rows.Count; i++)
{
dataB.Add(dgv_B[8, i].Value.ToString());
}
if (dataA == dataB)
{
lbl_resultado.Text = "Las certificaciones estan correctas";
}
else
{
var error = dataA.Except(dataB).Concat(dataB.Except(dataA));
var container = new HashSet<string>(error);
dgv_B.DataSource = container.ToList();
}
Theres the values that are needed:
The result of the code:
NOTE: the if (dataA == dataB) part, it's not the problem i need answer but thanks. The part needed its:
else
{
var error = dataA.Except(dataB).Concat(dataB.Except(dataA));
var container = new HashSet<string>(error);
dgv_B.DataSource = container.ToList();
}
NOTE 2: The main operation of the project is the verification of documents (for example, that no user has been modified)
If any value is changed you need to know which values were changed.
With
var error = dataA.Except(dataB).Concat(dataB.Except(dataA));
var container = new HashSet<string>(error);
dgv_B.DataSource = container.ToList();
I get the distinct values fron dataA and dataB, but I can't get it to show me the texts that appear.
NOTE:
Here's your problem:
if (dataA == dataB)
{
}
The HashSet<T> type does not override the == operator.
Consequently dataA == dataB performs only a reference equality comparison, which means the same thing as Object.ReferenceEquals( dataA, dataB ), which will always be false, as dataA and dataB are references to separate GC objects.
Instead, to compare both HashSets to see if they are both equivalent use (the confusingly named) SetEquals() method:
if( dataA.SetEquals( dataB ) )
{
lbl_resultado.Text = "Las certificaciones estan correctas";
}
Do not use Enumerable.SequenceEquals because that evaluates the HashSet as an ordered sequence of values, but a HashSet is a Mathematical Set, which is unordered and (AFAIK) its HashSet<T>.Enumerator iterator returns its elements in undefined order, so attempting to check two sets' set-equality by comparing sequences is incorrect.
workareaRefs is a string of random values splitted by comma i.e. 4,7,1,7 etc.
I am setting properties to TrackDataFilter and would like to set the Workareas
which is of type IList with the values in workareaRefs var.
So Workareas should contain the values in workareaRefs stored in the variable named r.
Can anyone help me achieve this?
var workareasRefs = workareaRefs.Split(',');
var r = new TrackDataFilter
{
DatePreset = preset,
Workareas = new List<TrackFilterGenericRef>
{
new TrackFilterGenericRef
{
Ref = 2, Type = Enums.ContentTypes.Workarea
}
},
};
Well, I am not sure If I understand your question correctly, so by guessing a bit, I would assume you want to do the following
WorkAreas = new List(workareasRefs);
Is there a way to shorten this code below. (expecting 20+ values)
The values will always remain in the same order.
string[] values = line.Split(',');
LogEntry entry = new LogEntry()
{
Id = values[0],
Service = values[1],
Name = values[2],
Process = values[3],
type = values[4]
[...]
};
I personally do not know of a simplified way of doing this -- somewhere this code would need to exist. However, you could use a mapper solution like AutoMapper to set up a mapping. At least this your handlers or actions aren't bloated with assignment logic.
Hope this helps a bit.
Looking forward to reading other answers.
You can add to LogEntry constructor with one param string line and move logic into constructor.
Then code will be look like
LogEntry entry = new LogEntry(line);
And in constructor something like this:
public void LogEntry(string line)
{
string[] values = line.Split(',');
Id = values[0],
Service = values[1],
Name = values[2],
Process = values[3],
type = values[4]
[...]
}
This code must be somewhere.
Is it better solution depends on the situation. If you often used the object initializer that will greatly simplify the code. If you do not it's probably not have much of a difference.
From your question, you are trying to avoid those twenty lines of setting the values. How about using a reflection based solution like the one below ?
string[] values = line.Split(',');
var orderedLogEntryPropertyNames =
new string[]{ "Id", "Name", "Process" };
//list all the LogEntry property names in the order that map to the values
var logEntry = new LogEntry();
var logEntryProperties = typeof(LogEntry).GetProperties();
for (int i = 0; i < values.Length; i++)
{
var propertyToSet =
logEntryProperties.First(p => p.Name.Equals(orderedLogEntryPropertyNames[i]));
propertyToSet.SetValue(logEntry, values[i]);
}
I created the following class:
class TrdRamValue
{
double Value = 0.0;
TrdState State = TrdState.Ok;
DateTime dt = DateTime.UtcNow;
}
I then created a list with this class to store the information:
List<TrdRamValue> DMSrows = new List<TrdRamValue> ();
And I use the following inside a Handler to constantly insert values every second:
string[] value = new string[3];
value[0] = val;
value[1] = val.Error.ToString ();
value[2] = val.Time.ToString ();
DMSrows.AddRange (value);
But in code it keeps saying that I have an error in my argument, that I can't convert string[] to System.Collections.Generic.IEnumerable.
I'm completely lost on this one...
ANSWER:
It was just a minor error from my part, and I also took huMpty duMpty suggestion since he's completely right, I don't need that string array.
All I had to do was make the class and the variables inside public in order to do what huMpty duMpty told me.
public class TrdRamValue
{
public double Value = 0.0;
public TrdState State = TrdState.Ok;
public DateTime dt = DateTime.UtcNow;
}
Then apply huMpty duMpty suggestion:
TrdRamValue value = new TrdRamValue() ;
value.Value = val;
if (!val.Error) {
value.State = TrdState.Ok;
}
else if (val.Error) value.State = TrdState.Error;
value.dt = val.Time;
DMSrows.Add (value);
Your List is not a List<string> but a List<TrdRamValue>. Therefore, you cannot add strings to the list. You can only add instances of TrdRamValue, or, in the case of AddRange, an IEnumerable (such as an array) of TrdRamValue.
So you can do this:
TrdRamValue toAdd = new TrdRamValue { Value = val, State = ..., dt = ... };
dmsRows.Add(toAdd);
(btw naming a variable DMSRows does not fit with the .net naming conventions).
You're trying to add strings to a list of TrdRamValue objects. Your list is type-safe, which means you are only allowed to add TrdRamValue objects to it.
Not sure why you need string array here.
Also you don't need List.AddRange here since you adding one item. You can use List.Add
DMSrows.Add(new TrdRamValue{
Value =val,
State =val.Error,
dt =val.Time
});
I think I understand returning records of an anonymous type from But in this I want to create NEW CatalogEntries, and set them from the values selected. (context is a Devart LinqConnect database context, which lets me grab a view).
My solution works, but it seems clumsy. I want to do this in one from statement.
var query = from it in context.Viewbostons
select it;
foreach (GPLContext.Viewboston item in query)
{
CatalogEntry card = new CatalogEntry();
card.idx = item.Idx;
card.product = item.Product;
card.size = (long)item.SizeBytes;
card.date = item.Date.ToString();
card.type = item.Type;
card.classification = item.Classification;
card.distributor = item.Distributor;
card.egplDate = item.EgplDate.ToString();
card.classificationVal = (int)item.ClassificationInt;
card.handling = item.Handling;
card.creator = item.Creator;
card.datum = item.Datum;
card.elevation = (int)item.ElevationFt;
card.description = item.Description;
card.dirLocation = item.DoLocation;
card.bbox = item.Bbox;
card.uniqID = item.UniqId;
values.Add(card);
}
CatalogResults response = new CatalogResults();
I just tried this:
var query2 = from item in context.Viewbostons
select new CatalogResults
{ item.Idx,
item.Product,
(long)item.SizeBytes,
item.Date.ToString(),
item.Type,
item.Classification,
item.Distributor,
item.EgplDate.ToString(),
(int)item.ClassificationInt,
item.Handling,
item.Creator,
item.Datum,
(int)item.ElevationFt,
item.Description,
item.DoLocation,
item.Bbox,
item.UniqId
};
But I get the following error:
Error 79 Cannot initialize type 'CatalogService.CatalogResults' with a
collection initializer because it does not implement
'System.Collections.IEnumerable' C:\Users\ysg4206\Documents\Visual
Studio
2010\Projects\CatalogService\CatalogService\CatalogService.svc.cs 91 25 CatalogService
I should tell you what the definition of the CatalogResults is that I want to return:
[DataContract]
public class CatalogResults
{
CatalogEntry[] _results;
[DataMember]
public CatalogEntry[] results
{
get { return _results; }
set { _results = value; }
}
}
My mind is dull today, apologies to all. You are being helpful. The end result is going to be serialized by WCF to a JSON structure, I need the array wrapped in a object with some information about size, etc.
Since .NET 3.0 you can use object initializer like shown below:
var catalogResults = new CatalogResults
{
results = context.Viewbostons
.Select(it => new CatalogEntry
{
idx = it.Idx,
product = it.Product,
...
})
.ToArray()
};
So if this is only one place where you are using CatalogEntry property setters - make all properties read-only so CatalogEntry will be immutable.
MSDN, Object initializer:
Object initializers let you assign values to any accessible fields or properties of an
object at creation time without having to explicitly invoke a constructor.
The trick here is to create a IQueryable, and then take the FirstOrDefault() value as your response (if you want a single response) or ToArray() (if you want an array). The error you are getting (Error 79 Cannot initialize type 'CatalogService.CatalogResults' with a collection initializer because it does not implement 'System.Collections.IEnumerable') is because you're trying to create an IEnumerable within the CatalogEntry object (by referencing the item variable).
var response = (from item in context.Viewbostons
select new CatalogEntry()
{
idx = item.Idx,
product = item.Product,
size = (long)item.SizeBytes,
...
}).ToArray();
You don't have to create anonymous types in a Linq select. You can specify your real type.
var query = context.Viewbostons.Select( it =>
new CatalogEntry
{
idx = it.idx,
... etc
});
This should work:
var query = from it in context.Viewbostons
select new CatalogEntry()
{
// ...
};