|
Message Removed
modified 23-Jan-20 4:49am.
|
|
|
|
|
I have a serialized collection of objects, such as
GroupEntity
- ConfigEntity
- DefinitionEntity
- ConfigEntity
- DefinitionEntity
- ConfigEntity
- DefinitionEntity
GroupEntity
- ConfigEntity
- DefinitionEntity
- ConfigEntity
- DefinitionEntity
- ConfigEntity
- DefinitionEntity
Given a generic type parameter T, how would you extract all items from the list for that type? So, if I have a class
public class Parser<T>
{
public T Data { get; set; }
public void LoadDataFromFile(string fileName)
{
List<GroupEntity> allData = Serialization.DeSerializeObject<List<GroupEntity>>(fileName);
Type parameterType = typeof(T);
}
}
and I instantiated it as
var parser = new Parser<ConfigEntity>();
parser.LoadDataFromFile(fileName);
or
var parser = new Parser<DefinitionsEntity>();
parser.LoadDataFromFile(fileName);
This should then extract ONLY the type of entities into the Data property defined by the generic parameter.
I could write some looping code, but I would then need conditional code for each type. Is this possible with Linq?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
That depends.
Do you have a list of objects of different types, where ConfigEntity and DefinitionEntity both inherit from GroupEntity ?
class GroupEntity { }
class ConfigEntity : GroupEntity { }
class DefinitionEntity : GroupEntity { } Or do you have a serialized object graph, where a GroupEntity contains one or more ConfigEntity objects, each of which contains one or more DefinitionEntity objects?
class GroupEntity
{
public List<ConfigEntity> ConfigEntities { get; }
}
class ConfigEntity
{
public List<DefinitionEntity> DefinitionEntities { get; }
}
class DefinitionEntity { } If it's the former, then OfType will do the trick:
public class Parser<T> where T : GroupEntity
{
public List<T> Data { get; set; }
public void LoadDataFromFile(string fileName)
{
List<GroupEntity> allData = Serialization.DeSerializeObject<List<GroupEntity>>(fileName);
Data = allData.OfType<T>().ToList();
}
} If it's the latter, then you're going to need conditional code for each type.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
1) They all individually inherit from EntityBase
2) I have a serialized object graph
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
The problem I see is that there's no way to make the Data property generic.
I can get all of the types like this:
private void LoadDataFromFile(string fileName)
{
try
{
List<RuleGroupEntity> groups = new List<RuleGroupEntity>();
List<RuleConfigurationEntity> configs = new List<RuleConfigurationEntity>();
List<RuleDefinitionEntity> definitions = new List<RuleDefinitionEntity>();
groups = Serialization.DeSerializeObject<List<RuleGroupEntity>>(fileName);
foreach (var group in groups)
{
configs.AddRange(group.RuleConfigurations);
foreach (var config in group.RuleConfigurations)
{
definitions.Add(config.RuleDefinition);
}
}
Type parameterType = typeof(T);
if (parameterType == typeof(RuleConfigurationEntity))
{
Data = (T)Activator.CreateInstance(typeof(T), configs);
}
}
catch (Exception e)
{
}
}
But I then need to assign one of those lists to Data T. Not sure how to convert that.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Something like this should work:
public class Parser<T> where T : EntityBase
{
public List<T> Data { get; set; }
public void LoadDataFromFile(string fileName)
{
List<RuleGroupEntity> groups = Serialization.DeSerializeObject<List<RuleGroupEntity>>(fileName);
switch (typeof(T))
{
case typeof(RuleGroupEntity):
{
Data = (List<T>)(object)groups;
break;
}
case typeof(RuleConfigurationEntity):
{
List<RuleConfigurationEntity> configs = groups.SelectMany(g => g.RuleConfigurations).ToList();
Data = (List<T>)(object)configs;
break;
}
case typeof(RuleDefinitionEntity):
{
List<RuleDefinitionEntity> definitions = groups.SelectMany(g => g.RuleConfigurations).Select(c => c.RuleDefinition).ToList();
Data = (List<T>)(object)definitions;
break;
}
default:
{
throw new NotSupportedException($"Type '{typeof(T)}' is not supported.");
}
}
}
} However, I'm never entirely convinced by a generic type which switches on the type parameter. Perhaps you could use specific parser types instead?
public abstract class Parser<T> where T : EntityBase
{
public List<T> Data { get; set; }
public void LoadDataFromFile(string fileName)
{
List<RuleGroupEntity> groups = Serialization.DeSerializeObject<List<RuleGroupEntity>>(fileName);
LoadDataFromGroups(groups);
}
protected abstract void LoadDataFromGroups(List<RuleGroupEntity> groups);
}
public class RuleGroupEntityParser : Parser<RuleGroupEntity>
{
protected override void LoadDataFromGroups(List<RuleGroupEntity> groups)
{
Data = groups;
}
}
public class RuleConfigurationEntityParser : Parser<RuleConfigurationEntity>
{
protected override void LoadDataFromGroups(List<RuleGroupEntity> groups)
{
Data = groups.SelectMany(g => g.RuleConfigurations).ToList();
}
}
public class RuleDefinitionEntityParser : Parser<RuleDefinitionEntity>
{
protected override void LoadDataFromGroups(List<RuleGroupEntity> groups)
{
Data = groups.SelectMany(g => g.RuleConfigurations).Select(c => c.RuleDefinition).ToList();
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
OK, so I implemented your first code snippet. It works.
What I left out before was that this all goes in a repository. I currently have a MongoDB repo, and now I'm implementing the IRepository interface to deal with the serialized version of the data. Now I have a new issue:
This Works
public T Get(Guid id)
{
return Data.Where(x => x.Id == id).FirstOrDefault();
}
This Doesn't Compile
public T Get(Expression<Func<T, bool>> predicate)
{
return Data.Where(predicate).FirstOrDefault();
}
The error is "'List<t>' does not contain a definition for 'Where' and the best extension method overload 'Queryable.Where<t>(IQueryable<t>, Expression<func<t, bool="">>)' requires a receiver of type 'IQueryable<t>'"
The problem is that List<t> isn't an IQueryable. If I change method signaature to accept a delegate instead of an expression, it works.
public T Get(Func<T, bool> predicate)
{
return Data.Where(predicate).FirstOrDefault();
}
I could add this method to the interface, but I'd rather not change existing code if I don't have to. And it causes abiguity beetween the two Get methods.
I'd like to hear your thoughts on this. And thanks for your help so far.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
How about:
public T Get(Expression<Func<T, bool>> predicate)
{
return Data.AsQueryable().Where(predicate).FirstOrDefault();
} Queryable.AsQueryable Method (System.Linq) | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
This seems to work
Interface Change
T Get(Func<T, bool> predicate);
Mongo Repo
public T Get(Func<T, bool> predicate)
{
var collection = GetCollection().AsQueryable();
return collection.Where(predicate).FirstOrDefault();
}
XML Repo
public T Get(Func<T, bool> predicate)
{
return Data.AsQueryable().Where(predicate).FirstOrDefault();
}
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
example of generic return filter ... you write the Linq version
... usage example in some method:
required: using GRFExample;
var gevalues = Example.GetByType<GroupEntity>(Example.Test1().ToArray()).Cast<GroupEntity>();
var cevalues = Example.GetByType<ConfigEntity>(Example.Test1().ToArray()).Cast<ConfigEntity>();
var devalues = Example.GetByType<DefinitionEntity>(Example.Test1().ToArray()).Cast<DefinitionEntity>();
using System.Collections.Generic;
namespace GRFExample
{
public static class Example
{
private static int id = 0;
public static IEnumerable<GroupEntity> Test1()
{
for (var i = 0; i < 5; i++)
{
var ge = new GroupEntity();
for (var j = 0; j < 4; j++)
{
var ce = new ConfigEntity();
ce.dee = new DefinitionEntity(id++);
ge.cees.Add(ce);
}
yield return ge;
}
}
public static IEnumerable<TheBase> GetByType<T>(params GroupEntity[] bees)
{
var pType = typeof(T).Name;
foreach (var b in bees)
{
switch (pType)
{
case "B":
yield return b;
break;
case "C":
foreach (var c in b.cees) yield return c;
break;
case "D":
foreach (var c in b.cees) yield return c.dee;
break;
}
}
}
}
public class TheBase
{
}
public class GroupEntity : TheBase
{
public List<ConfigEntity> cees = new List<ConfigEntity>();
}
public class ConfigEntity : TheBase
{
public DefinitionEntity dee;
}
public class DefinitionEntity : TheBase
{
public int id;
public DefinitionEntity(int id)
{
this.id = id;
}
}
}
«One day it will have to be officially admitted that what we have christened reality is an even greater illusion than the world of dreams.» Salvador Dali
|
|
|
|
|
Use interfaces; "generics" aren't that generic in this case.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
So I'm working on a plugin for an application. So I'm creating a ClassLibrary in C#. I'm stuck at this point where it throws that error telling me that System.data.sqlite.dll isn't found. But I've checked it and even manually replaced the file, and it's there.
Another thing to note is that since it's a ClassLibrary, there no executable, it runs when the button on the application is pressed to run the plugin. Also this is my first time working with sqlite in C#. So I followed someone's instructions, which told me to simply get sqlite core from nuget and get dapper from nuget. I've done that. Do I need to get something from system.data.sqlite's website?
Please excuse the way I've asked too many question, but I'm just puzzled. This is my first time working with a Class Library and I never thought it'd be so much different to a console or winform application.
Regards
|
|
|
|
|
If it's a plugin, is it looking for the file in the directory of the application you've plugged into, rather than in the directory of the plugin?
Maybe you could use the AssemblyResolve event to locate the file?
Resolve assembly loads | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
hi all
i draw a canvas on page in 2 row and 2 col format.
now i want to flip vertically them,
please help me how can i flip it on its same location.
thanks in advance.
|
|
|
|
|
What have you tried?
Where are you stuck?
What help do you need?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
bool Draw_Mirror_Image = checkBox_mirror_image.Checked;
bool Flip_horz_or_vert = radioButton_mirr_img_FV.Checked;
StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;
stringFormat.FormatFlags = StringFormatFlags.LineLimit;
stringFormat.Trimming = StringTrimming.Word;
RectangleF rect2 = panel2.ClientRectangle;
float image_draw_wd = 200;
float image_draw_ht = 100;
int X = 0;
int Y = 0;
Brush myBrush = new SolidBrush(Color.FromArgb(128, Color.Blue));
int ROW=3;
int COL=3;
Pen pen = new Pen(Color.Red, 4);
float Zoom_Value = 100;
float X_SF = 1;
float Y_SF = 1;
string draw_text = "35";
Font draw_text_Font = new Font("Microsoft Sans Serif", 18, FontStyle.Bold);
for (int r = 1; r <= ROW; r++)
{
X = 0;
for (int cl = 1; cl <= COL; cl++)
{
draw_text = "ROW : " + r.ToString() + "\nCOL : " + cl.ToString();
Rectangle dr_rect = new Rectangle(new Point(X, Y), new Size((int)image_draw_wd, ((int)image_draw_ht)));
if (Draw_Mirror_Image)
{
if (Flip_horz_or_vert == false)
{
pe.ScaleTransform(-X_SF, Y_SF);
pe.TranslateTransform(-((image_draw_wd) * (float)(Zoom_Value / 100f)), 0);
}
else
{
pe.ScaleTransform(X_SF, -Y_SF);
pe.TranslateTransform(0, -((image_draw_ht) * (float)(Zoom_Value / 100f)));
}
}
pe.DrawString(draw_text, draw_text_Font, myBrush, dr_rect, stringFormat);
pe.DrawRectangle(pen, dr_rect);
X = X + (int)image_draw_wd;
}
Y = Y + (int)image_draw_ht;
}
i use this to drawing
please chk this
[^]1.png - Google Drive[^]
[^]2.png - Google Drive[^]
[^]3.png - Google Drive[^]
how all cell flip on its same position
please help me
modified 23-Jan-20 1:25am.
|
|
|
|
|
"Move" row 1 to row 2; move 2 to 1. (by exchanging ".Top" properties).
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
how to export the data from stored procedure to excel?
|
|
|
|
|
What have you tried?
Where are you stuck?
What help do you need?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
NB: You can't use Office Interop in an ASP.NET application:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
Use a tool like EPPlus[^], ClosedXML[^], or The OpenXML SDK[^] to generate an Excel file.
For example, EPPlus provides both LoadFromDataReader and LoadFromDataTable methods which you could use to load the data from your query into the Excel file.
DataTable dt = LoadDataFromStoredProcedure();
var pck = new ExcelPackage();
var wsDt = pck.Workbook.Worksheets.Add("FromDataTable");
wsDt.Cells["A1"].LoadFromDataTable(dt, true, TableStyles.Medium9);
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
pck.SaveAs(Response.OutputStream);
Response.Flush();
Response.SuppressContent = true;
Context.ApplicationInstance.CompleteRequest();
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Export as CSV.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
I can not use int j =Convert.Int32(ReadLine()); in Visual Stdio 2019
|
|
|
|
|
Don't post the same question all over the site either: you have the answer in your QA post, so spreading the same thing all over the place just wastes even more time that reposting it in QA repeatedly does. And that really annoys people - and annoyed people are generally not as helpful as happy people.
All it does is make you look rude, arrogant, and pretty desperate. You want to come over like that? Be my guest - but don't expect help from volunteers with other things to do ...
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Yes you can. Why can't you?
Social Media - A platform that makes it easier for the crazies to find each other.
Everyone is born right handed. Only the strongest overcome it.
Fight for left-handed rights and hand equality.
|
|
|
|
|
Hi
I'm quit new to C#, I moved from Autoit to C# mostly due to most AV-vendors keep flagging Autoit as virus :/
I've been googling for the better part of a week, but haven't found any answer.
What I looking for is an equivalent to Autoit's code stripper.
What the stripper does is, at compile time it strips all comments from the code, and renames all vars and functions to "short code", it also removes all unused functions.
An Autoit example:
If GUICtrlRead($idCb_Edit_Chosen_Lot) = $GUI_CHECKED Then
; We updates the database, with the data from the array
_SQLite_Exec(-1, "UPDATE tbl_data SET date='" & $sDateTime & "', lot='" & $aData[1] & "', packing='" & $aData[2] & _
"', sort_number='" & $aData[3] & "', sort_name=" & _SQLite_FastEscape($aData[4]) & ", type='" & $aData[5] & "', grower='" & $aData[6] & _
"', customer=" & _SQLite_FastEscape($aData[7]) & ", comment=" & _SQLite_FastEscape($aData[8]) & " WHERE date='" & $g_SDateTime & "';")
; Then we update the Listview
; In the list view we don't have seperate filds for sort number and name, so we need to combine thoes
$aData[3] &= ' ' & $aData[4] ; Combine sort number and name in to $aData[3]
_ArrayDelete($aData, 4) ; then we removes (deletes) the 4'th index from the array $aData
; Now we creates a loop to update the listview with the data from the array we just changed
For $i = 0 To 7 Step 1 ; Sins we deletede on index from the array, we only run from 0 to 7
; Insert the data into listview
_GUICtrlListView_SetItemText($idListView_Overview, $g_iIndex, $aData[$i], $i)
Next
GUICtrlSetData($idLbl_LotNr, StringFormat("%06d", $g_iLot - 1)) ; Set the last used lot -1 (we add + 1 later in the script)
$g_iLot = Null ; Clear the global lot value
GUICtrlSetState($idCb_Edit_Chosen_Lot, $GUI_UNCHECKED) ; Unchecks the Checkbox
Else ; If it's not a lot edit then
; We Adds the data to the database
_SQLite_Exec(-1, "INSERT INTO tbl_data VALUES ('" & $aData[0] & "', '" & $aData[1] & "', '" & $aData[2] & _
"', '" & $aData[3] & "', " & _SQLite_FastEscape($aData[4]) & ", '" & $aData[5] & "', '" & $aData[6] & _
"', " & _SQLite_FastEscape($aData[7]) & ", " & _SQLite_FastEscape($aData[8]) & ");")
; Creating an array we can use to adde the data to the listview
Local $aListViewAdd[1][8]
; Combine the Sort number and name
$aData[3] &= ' ' & $aData[4]
; Update the array, by remove/delete the 4'th index (sortname)
_ArrayDelete($aData, 4)
; Creating a loop to add data to the array
For $i = 0 To 7 ; We only run from 0 to 7 course we did delete one index in the array
$aListViewAdd[0][$i] = $aData[$i] ; Add the data to the new array
Next
; Add the data to the listview using the new array, we just created
_GUICtrlListView_AddArray($idListView_Overview, $aListViewAdd)
; If the user have choosen to reuse the previus lotnumber
If $g_bReuse = True Then
$g_bReuse = False
GUICtrlSetState($idCb_Reuse_Pre_Lot, $GUI_UNCHECKED)
EndIf
EndIf
After stripping:
If GUICtrlRead($idCb_Edit_Chosen_Lot) = 1 Then
_SQLite_Exec(-1, "UPDATE tbl_data SET date='" & $sDateTime & "', lot='" & $aData[1] & "', packing='" & $aData[2] & "', sort_number='" & $aData[3] & "', sort_name=" & _SQLite_FastEscape($aData[4]) & ", type='" & $aData[5] & "', grower='" & $aData[6] & "', customer=" & _SQLite_FastEscape($aData[7]) & ", comment=" & _SQLite_FastEscape($aData[8]) & " WHERE date='" & $g_SDateTime & "';")
$aData[3] &= ' ' & $aData[4]
_ArrayDelete($aData, 4)
For $i = 0 To 7 Step 1
_GUICtrlListView_SetItemText($idListView_Overview, $g_iIndex, $aData[$i], $i)
Next
GUICtrlSetData($idLbl_LotNr, StringFormat("%06d", $g_iLot - 1))
$g_iLot = Null
GUICtrlSetState($idCb_Edit_Chosen_Lot, 4)
Else
_SQLite_Exec(-1, "INSERT INTO tbl_data VALUES ('" & $aData[0] & "', '" & $aData[1] & "', '" & $aData[2] & "', '" & $aData[3] & "', " & _SQLite_FastEscape($aData[4]) & ", '" & $aData[5] & "', '" & $aData[6] & "', " & _SQLite_FastEscape($aData[7]) & ", " & _SQLite_FastEscape($aData[8]) & ");")
Local $aListViewAdd[1][8]
$aData[3] &= ' ' & $aData[4]
_ArrayDelete($aData, 4)
For $i = 0 To 7
$aListViewAdd[0][$i] = $aData[$i]
Next
_GUICtrlListView_AddArray($idListView_Overview, $aListViewAdd)
If $g_bReuse = True Then
$g_bReuse = False
GUICtrlSetState($idCb_Reuse_Pre_Lot, 4)
EndIf
I have tried a lot of obfuscatore, but non worked correctly they did to0 much, leaving my code not working.
Is there some way one could do the same with a C# code, as the code above?
Not exactly obfuscation but more a slim down, and make the code a bit more unreadable.
Cheers
LR
|
|
|
|
|