Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 months ago.
Improve this question
Trying to convert Array of Objects to String using C#. Able to achieve the same using LINQ, however trying to make use of reusable functions which would accept array of Objects and return back string. Understand that generics must be used but it's been hard time understanding it. Thanks in advance!
public class HelloWorld {
public static void Main() {
Root root = new Root();
List<A> obj = new List<A>();
obj.Add(new A() { Code = "WAY"});
obj.Add(new A() { Code = "DOWN"});
obj.Add(new A() { Code = "WE"});
obj.Add(new A() { Code = "GO"});
root.A = obj;
string _Result = string.Join("-", root.A.Where(x => x.Code != "").Select(p => p.Code.ToString()).ToArray());
Console.WriteLine(_Result); //Expected OP: WAY-DOWN-WE-GO
Console.WriteLine(Utility.ToArray(root.A)); //System.Collections.Generic.List`1[A]
}
//Trying for much simpler Generic function here.
public class Utility{
public static string ToArray(IList<Object> obj){
foreach(var v in obj){
//generic function..
}
StringBuilder sb = new StringBuilder();
return sb.ToString();
}
}
}
public class Root
{
public List<A> A { get; set; }
public List<B> B { get; set; }
}
public class A
{
public string Code { get; set; }
}
public class B
{
public string Mode { get; set; }
}
If you're looking for a system that works without having to have your classes implement an interface (for objects you didn't create, for example), it's possible to use a Func<T, object> to select a specific property/field:
// IEnumerable is more generic over "lists" (sets, maps, etc)
// \/
public static string ToArray<T>(IEnumerable<T> obj, Func<T, object> func) {
return string.Join('-', obj.Select(func));
}
Usage example:
List<A> aObjects = new();
//add aObjects
List<B> bObjects = new();
//add bObjects
Console.WriteLine(Utilities.ToArray(aObjects, a => a.Code));
Console.WriteLine(Utilities.ToArray(bObjects, b => b.Mode));
Reference: How to join as a string a property of a class?
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm trying to dynamically populate a list of objects as follows:
using System;
using System.Collections.Generic;
namespace test
{
class MainClass
{
public static void Main(string[] args)
{
List<string> items = new List<string>() { "item1", "item2", "item3" };
List<MainObject> objects = new List<MainObject>();
foreach (var item in items)
{
objects.Add(new MainObject(item));
foreach (MainObject o in objects)
Console.WriteLine(o.getString());
}
}
}
class MainObject
{
public MainObject() { }
public MainObject(string theString) { nString = theString; cString = theString; }
private static string nString { get; set; }
private static string cString { get; set; }
public string getString() { return nString; }
}
}
I figure that since I'm using the "new" operator I'm instantiating a new object each loop, but it overwrites the previous entry every time.
It gives an output like the following:
item1
item2
item2
item3
item3
item3
It is side effect of the way how you use WriteLine, or, to be more precise, where you use WriteLine.
Modify your code to something like this:
List<Object> objects = new List<Object>();
foreach (var theString in stringList)
{
objects.Add(new Object(theString));
}
//this should be outside of first loop
foreach (Object object in objects)
{
Console.WriteLine(object.getValue());
}
The definition of MainClass is using static fields and that's causing their values to be overwritten each time a new MainObject is created.
There's only one memory location for each static field. In the constructor, that memory location is being assigned the value of the parameter, which overwrites any value previously passed to the constructor.
On the other hand, an instance (non-static) field has a separate location within each instance. In that case, the assignment affects that object instance and not any others.
All you have to do is remove the static modifier from those properties.
class MainObject
{
public MainObject() { }
public MainObject(string theString) { nString = theString; cString = theString; }
// Remove 'static' from these two declaration
private string nString { get; set; }
private string cString { get; set; }
public string getString() { return nString; }
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Looking for C# syntax to make the following code more elegant, compact and readable. The foreach with the multiple if's take up too much space and look too ugly. I'm thinking LINQ syntax maybe?
(srSys and desSys are strings, and srFl and desFl are ints. The final version will have better variable naming)
public static warMod Gen ( List<AtMap> atMaps ) {
List<AtMap> atMapList = new List<AtMap>();
foreach(var a in atMaps)
{
AtMap atMap = new AtMap();
if (!string.IsNullOrEmpty(a.srSys))
{
atMap.srSys = a.srSys;
}
if (!string.IsNullOrEmpty(a.desSys))
{
atMap.desSys = a.desSys;
}
if (a.srFl != null)
{
atMap.srFl = a.srFl;
}
if (a.desFl != null)
{
atMap.desFl = a.desFl;
}
atMapList.Add(atMap);
}
return new warMod {AtMapArr = atMapList}
}
You could simply put the if's hidden away forever inside of the AtMap class.
public static warMod Gen(List<AtMap> atMaps)
{
List<AtMap> atMapList = new List<AtMap>();
foreach (var a in atMaps)
atMapList.Add(new AtMap(a));
return new warMod { AtMapArr = atMapList };
}
public class AtMap
{
public AtMap(AtMap a)
{
if (!string.IsNullOrEmpty(a.srSys))
srSys = a.srSys;
if (!string.IsNullOrEmpty(a.desSys))
desSys = a.desSys;
if (a.srFl != null)
srFl = a.srFl;
if (a.desFl != null)
desFl = a.desFl;
}
}
EDIT: Given that the overall logic of the function seems to just take an List<AtMap> type named AtMaps and make another List<AtMap> type named AtMapsList>. The function can simply be return new warMod {AtMapArr = atMaps};. However, the constructor can still be used at the part where AtMaps is made
// Use of constructor to initialize your class (AtMap.cs)
public class AtMap {
public string srSys, desSys;
public int? srFl, desFl;
public AtMap(string srSys, string desSys, int? srFl, int? desFl) {
if (!string.IsNullOrEmpty(a.srSys)) {
this.srSys = a.srSys;
}
if (!string.IsNullOrEmpty(a.desSys)) {
this.desSys = a.desSys;
}
if (a.srFl != null) {
this.srFl = a.srFl;
}
if (a.desFl != null) {
this.desFl = a.desFl;
}
}
}
When you initialize your class AtMap fields: srSys and desSys will be empty, srFl and desFl (for example: int) will be 0.
I think it can be like this:
public class AtMap
{
public string srSys {get; set;}
public string desSys {get; set;}
public int srFl {get; set;}
public int desFl {get; set;}
}
public static warMod Gen(List<AtMap> atMaps)
{
var atMapList = new List<AtMap>();
foreach (var a in atMaps)
{
var atMap = new AtMap
{
srSys = a.srSys,
desSys = a.desSys,
srFl = a.srFl ?? default(int),
desFl = a.desFl ?? default(int)
};
atMapList.Add(atMap);
}
return new warMod { AtMapArr = atMapList };
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have several data classes and want to select an item from a list. We want to use a lambda expression to do so. But it seems not to work as expected when the select property is in the base class.
Base Class
public class BaseData
{
public bool isSelected;
public int distance;
}
Derived class
public class PlayerData: BaseData
{
public string nickname
}
Some Logic
public class SelectData
{
public PlayerData GetPlayer()
{
List<PlayerData> playerdata = new List<PlayerData>();
// this list gets its data from a JSON file and is populated as expected.
// now we want to select the player data for processing.
PlayerData player = playerdata.Find(x => x.isSelected);
// on this part we unexpected results, when i move the isSelected to the class PlayerData it works perfect but than it is not possible to write a generic extensions with these Data classes.
return player;
}
}
We want to use a extension something like
public static int AddToDropDown<T>(this Dropdown dropdown,
List<T> baseDataList,
string displayText,
string iconName,
bool isSelected) where T : new() {
enter code here --- add to dropdown and add the item to PlayerData or ...
}
There are no complier errors... what is wrong?
For me it works fine:
See this example here, probably there is something else causing the issue:
public void Main()
{
List<PlayerData> playerdata = new List<PlayerData>
{
new PlayerData
{
isSelected = true,
distance = 3,
nickname = "First",
},
new PlayerData
{
isSelected = true,
distance = 3,
nickname = "Second",
},
new PlayerData
{
isSelected = true,
distance = 3,
nickname = "Third",
}
};
PlayerData player = playerdata.Find(x => x.isSelected);
Console.WriteLine(player);
}
public class BaseData
{
public bool isSelected;
public int distance;
}
public class PlayerData: BaseData
{
public string nickname;
public override string ToString() { return this.nickname;}
}
The result is 'First' as expected since it is the first player in the list.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to compare a value and a value of an object in a list...
and be able to use it with others object type lists.
like :
ID = generateID();
CheckUsableID(ID, TeamList);
// or CheckUsableID(ID, PlayerList);
Please help me !
// C# Code
public bool CheckUsableID(int id, List<object> list)
{
foreach(var object in list)
{
if (list<object>.id == id)
{
return false;
}
}
return true;
}
I just want to compare them.
In order to check lists of different types you'll need something either an interface or base class that all the objects that could appear in a list implement. When you have that you can use generics when defining the method.
For example, we could define an interface:
public interface IDomainObject
{
int id { get; set; }
}
Then we can redefine the method with generics:
public bool CheckUsableID<T>(int id, List<T> list) where T : IDomainObject
{
foreach(var item in list)
{
if (item.id == id)
{
return false;
}
}
return true;
}
Assuming that TeamList is a List<Team> or similar and PlayerList is a List<Player> or similar you will need to just ensure Team and Player implement the IDomainObject interface and you'll be able to pass them to the CheckUsableID method:
List<Team> TeamList = new List<Team>();
//populate TeamList from somewhere
ID = generateID();
CheckUsableID(ID, TeamList);
If you create a base class you could then put the method in the base class:
Why not use LINQ? There's no need to loop through the entire list. Let Linq do the dirty work for you.
bool hasUsableID = TeamList.Any(t => t.Id == ID);
bool hasUsableID = PlayerList.Any(p => p.Id == ID);
I'm assuming
TeamList is a List< Team > and Team has the property ID exposed
PlayerList is a List< Player > and Player has the property ID exposed
You need to use reflection. Here you go with your modified sample !
// C# Code
public bool CheckUsableID(int id, List<object> list)
{
foreach (var obj in list)
{
var objId = (int)GetValueFromObj(obj, "id");
if (objId == id)
{
return false;
}
}
return true;
}
private object GetValueFromObj(object obj, string propertyName)
{
return obj.GetType().GetProperty(propertyName).GetValue(obj);
}
First off, you have plenty of syntax errors and improper use of the key words. I will provide you with an example and you can fix it yourself:
In this case, I'm assuming <object> is actually a class, right? In that case, you need to redefine the object.
public bool CheckUsableID(int id, List<clsSomeObject> someTeamList)
{
clsSomeObject newObject = new clsSomeObject();
newObject = someTeamList;
foreach(var object in newObject)
{
if (newObject.id == id)
{
return false;
}
}
return true;
}
Try something like this:
you Post a list of ID's that you whant to compare, and GET a list with ID.
public List<SomeObject > CheckUsableID(int id, List<SomeObject > list)
{
var listUsableId = new List<SomeObject >();
foreach(var object in list)
{
if (object.Id == id)
{
listUsableID.add(object);
}
}
return listUsableId;
}
public class SomeObject
{
public int Id { get; set }
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have two classes, SuperHero and SuperTeam. How can I add instances of SuperHero to the TeamList property of SuperTeam?
namespace SuperLeague
{
class SuperHero
{
string SuperHeroName;
string ComicTitle;
public SuperHero()
{
SuperHeroName = "";
ComicTitle = "";
}
public SuperHero(string nSuperHeroName,string nComicTitle)
{
SuperHeroName = nSuperHeroName;
ComicTitle = nComicTitle;
}
public string nSuperHeroName
{
get { return SuperHeroName; }
set { SuperHeroName = nSuperHeroName; }
}
public string nComicTitle
{
get { return ComicTitle; }
set { ComicTitle = nComicTitle; }
}
}
class SuperTeam
{
string SuperTeamName;
List<SuperTeam> TeamList = new List<SuperTeam>();
public SuperTeam()
{
SuperTeamName = "";
}
public SuperTeam(string nSuperTeamName)
{
SuperTeamName = nSuperTeamName;
}
public string nSuperTeamName
{
get { return SuperTeamName; }
set { SuperTeamName = nSuperTeamName; }
}
public void SuperTeamAdd(SuperHero NewHero)
{
TeamList.Add(NewHero);
}
public void SuperTeamRemove(string NameToFind)
{
SuperHero SuperHeroToDel = null;
for (int i = 0; i < TeamList.Count; i++)
{
if (TeamList[i].nSuperHeroName.Equals(NameToFind))
{
SuperHeroToDel = TeamList[i];
TeamList.Remove(SuperHeroToDel);
}
}
}
}
}
Given the provided code;
Your SuperHero class represents a single hero.
Your SuperTeam class represents a single team which contains a list of hero's.
If you want multiple team's with super hero's we'll need another container. Something like
List<SuperTeam> listOfTeams;
This will allow you to store multiple "SuperHero"'s into the "SuperTeam", and store multiple teams in "listOfTeams"
Since you mention you want to get a team used on it's name, you could also use a "Dictionary<string, SuperTeam> CollectionOfTeams". This will allow you to get a team from 'CollectionOfTeams' using the a key.
SuperHero superMan = new SuperHero();
// fill in superMan properties
SuperTeam flyingTeam = new SuperTeam();
flyingTeam.members.Add(superMan);
// add more super hero members that fly to the team
collectionOfTeams.Add("Flying", flyingTeam);
// Getting the 'flying team'
SuperTeam currentTeam = CollectionOfTeams["Flying"];
Hope this helps,
Like this:
SuperHero hero = new SuperHero();
SuperTeam team = new SuperTeam();
team.TeamList.Add(hero);
Also, change the TeamList property to this:
List<SuperHero> TeamList;