C# Returning custom class Array - c#

I have a custom class defined:
class Car
{
public string a;
public string b;
public string c;
public static void GetCar()
{
var car = new Car[4];
for(int i=0; i<4; ++i)
{
novica[i]= new Novica();
novica[i].a="abc";
novica[i].b="abc";
novica[i].c="abc";
}
}
}
This fills the array with values, and now I would like to use this array with the values it gets (loading string from HTML) in a function that is not part of this class. Is it possible and if so, how?

In order to use it elsewhere, you would need to return the array from your function, like so:
public static Car[] GetCar()
{
var car = new Car[4];
for(int i=0; i<4; ++i)
{
car[i]= new Novica();
car[i].a="abc";
car[i].b="abc";
car[i].c="abc";
}
return car;
}

You can't. Your method doesn't actually return anything.
If you were to change the method signature to return the array the method creates:
public static Car[] GetCar()
{
// Body
return car;
}
The call would become as simple as:
var cars = Car.GetCar();

I suggest a slightly different construction. Provide an array containing all cars as static property
public class Car
{
public static Car[] AllCars { get; private set; }
public Car()
{
// Class and constructor somewhat simplyfied.
AllCars = new Car[4];
for (int i = 0; i < 4; ++i) {
AllCars[i] = new Novica();
}
}
}
Now you can work with cars like this
foreach (Car car in Car.AllCars) {
// do something with car
}
Or access a specific car with
string a = Car.AllCars[i].a;

Related

When should you create classes that are derived from IEnumerator/IEnumerable?

I do understand how both interfaces (IEnumerator and IEnumerable) work and what they are used for. However, I never quite understood when to create a class that is derived from one of these two interfaces. You can do a foreach loop on a list, on an array, and other generic collections as far as I am aware without having to create a class like I did in my code:
class Program
{
public static int[] array = new int[3] { 1, 2, 3 };
static void Main(string[] args)
{
var Enumerable = new Aninfiniteenumerator();
foreach(var i in infiniteEnumerable)
{
Console.WriteLine($"I is {i}");
}
Console.ReadKey();
}
}
class Aninfiniteenumerator : IEnumerable<int> //Creating a class that is derived from IEnumerable
{
public IEnumerator GetEnumerator()
{
return new MyInfiniteEnumer(Program.array);
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
return new MyInfiniteEnumer(Program.array);
}
}
public class MyInfiniteEnumer : IEnumerator<int> ////Creating a class that is derived from IEnumerator
{
private int[] values;
private int index = -1;
public int Current => values[index];
object IEnumerator.Current => Current;
public MyInfiniteEnumer (int [] values)
{
this.values = values;
}
public void Dispose()
{
}
public bool MoveNext()
{
index++;
return index < values.Length;
}
public void Reset()
{
}
}
PS. I know that my enumerators are called "infinite enumerators" yet they are not infinite. So, as I have said, it is possible to do a foreach loop over a generic list/an array without having to create an IEnumerable/IEnumerator classes:
class Program
{
static void Main(string[] args)
{
Random rand = new Random();
List<Car> vehicles = new List<Car>();
for(int i = 0; i < 100; i++)
{
vehicles.Add(new Car(rand.Next(1970,2021), "Honda"));
}
foreach(var car in vehicles)
{
Console.WriteLine(car.yearProduced + ", " + car.model);
}
Console.ReadKey();
for (int i = 0; i < 100; i++)
{
vehicles.Add(new Car(rand.Next(1970, 2021), "Subaru"));
}
foreach (var car in vehicles)
{
Console.WriteLine(car.yearProduced + ", " + car.model);
}
Console.WriteLine(vehicles.Count());
Console.ReadKey();
}
}
class Car
{
public string model { get; set; }
public int yearProduced { get; set; }
public Car (int year, string model)
{
yearProduced = year;
this.model = model;
}
}
Back to my question, I wrote the first code to be able to do a foreach loop over the var called "Enumerable". I only wrote this code for practice and see no practical use of creating classes that are derived from IEnumerable and IEnumerator. So, my question is, what are some situations where you'd have to create a class that is derived from one of these two interfaces?
A good example of a custom structure that could use the enumerator is the binary tree.
A simplest tree would be
public class Tree
{
public Tree Left { get; set; }
public Tree Right { get; set; }
public object Value { get; set; }
}
This definition can be used to compose arbitrary trees:
var root = new Tree()
{
Left = new Tree() { Value = 1 },
Right = new Tree() { Value = 2 },
Value = 3
}
Note that my tree is balanced but actual trees don't have to be.
Now, how are you supposed to enumerate all values? It's not that easy, in each node you have to decide whether or not it has subnodes and when you are done at the node, you have to go back to its parent and explore all paths.
But the client code is not interested in whether or not it's difficult, it expects the code to be
foreach ( var val in root )
{
// I want all values from the tree here!
}
This is when the idea of enumeration starts to make sense. It's not only about simple, linear structures, like arrays or lists!
public class Tree : IEnumerable
{
public IEnumerator GetEnumerator()
{
if ( Left != null ) foreach ( var e in Left ) yield return e;
if ( Right != null ) foreach ( var e in Right ) yield return e;
yield return Value;
}
}
I hope this example sheds some lights on the issue.

c# How to get the original object of list element Not references

I have two classes: ClassA and Test
I want to set Test.classA = null by ClassA.Clean().
I dont want use Test.classA directly
The code:
public class ClassA
{
private static List < ClassA > list = new List < ClassA > ();
public ClassA()
{
list.Add(this);
}
public static void Clean()
{
for (var i = 0; i < list.Count; i++)
{
//var classA = list[i];
//classA = null;
}
}
}
public class Test
{
private static ClassA classA;
void DoSomething()
{
if (classA == null)
classA = new ClassA();
}
}
Ok man:
1. Sorry for bad english :D - writes litelary 2 basic sentences^^ (no hate)
So you have a class test which contains an object of classA...and you want to "clear" classA
I dont know a way to "clear" an object, but you can clear the list in classA whitch list.clear().
Btw i dont realy understand what you are trying to do....you have a classA with a list and you fill this list with the same object of classA and this object contains a list which contains classA which contains a list........ you get the point...
I think you need one more class for List of ClassA, or example
public class ListClassA
{
public list;
public ClassA()
{
list = new List<ClassA>();
}
public void Clean()
{
for (var i = 0; i < list.Count; i++)
{
list.Clear();
}
}
}
public class ClassA
{
private static ListClassA list = new ListClassA();
public ClassA()
{
list.Add(this);
}
public static void Clean()
{
list.Clear();
}
}
OR
you need collections.generic, because is has Clear() function.

c# Nested Accessors?

I know how to do:
Class class = new Class();
class.Accessor
I don't know how to do:
class.Property.Accessor
class.Property.Subproperty.Accessor
class.Property.Subproperty.YetAnotherSubproperty.Accessor
Example analogy:
ListBox.Items.Count
An analogy to help explain (don't take it literally), I know how to create ListBox, I know how to create Count, but I don't know how to create Items
Something like
class Animal
{
// gets the heart of this animal
public HeartType Heart
{
get
{
...
}
}
}
class HeartType
{
// gets the number of beats per minute
public int Rate
{
get
{
...
}
}
}
Then for a given by var a = new Animal(); you could say
int exampleRate = a.Heart.Rate;
Well, your question is quite cryptic, but i'll try.
Subproperties are just instances of other classes (or static classes) with their own properties.
Example:
class Class1
{
public Class2Instance{get;set;}
public Class1()
{
Class2Instance =new Class2();
}
}
class Class2
{
public string Greeting = "Hello";
}
//////
var c = new Class1();
Console.WriteLine(c.Class2Instance.Greeting);
I'm not sure if I understood your question properly. But in your analogy, Items is a property/field of ListBox and the type of that property/field could be some collection. And that collection has the Count property.
I recently answered for similar question but it is more to do with a method chaining called FluentInterface style.
In you case, it seems you are trying to call properties/public fields, which are part of type; and these types are referenced in a nested fashion. With this in mind, the idea can be demonstrated as below;
class Program
{
static void Main(string[] args)
{
var one=new LevelOne();
Console.WriteLine(one.LevelTwo.LevelThree.LastLevel);
}
}
internal class LevelOne
{
public LevelOne()
{
LevelTwo = LevelTwo ?? new LevelTwo();
}
public LevelTwo LevelTwo { get; set; }
}
internal class LevelTwo
{
public LevelTwo()
{
LevelThree = LevelThree ?? new LevelThree();
}
public LevelThree LevelThree { get; set; }
}
internal class LevelThree
{
private string _lastLevel="SimpleString";
public String LastLevel { get { return _lastLevel; } set { _lastLevel = value; } }
}

Make an array of classes

I need to create an array of another class.
Example:
namespace std
{
public class Car
{
double number,id;
public Car()
{
// initializing my variables for example:
number = Random.nextdouble();
}
}
public class Factory
{
public Factory(int num)
{
Car[] arr = new Car(num);
}
}
}
The problem is I get this error:
'Car' does not contain a constructor that takes '1' arguments
I just need to have an array of Car in Factory class (the car variables are initialized with its constructor).
You've just used the wrong brackets. You always use square brackets for arrays and indexers. Round brackets are to invoke methods, constructors etc. You meant:
car[] arr = new car[num];
Note that conventionally .NET types are Pascal-cased, so your types should be Car and Factory rather than car and factory.
Also note that after creating the array, each element will be a null reference - so you shouldn't write:
// Bad code - will go bang!
Car[] cars = new Car[10];
cars[0].SomeMethod(0);
Instead:
// This will work:
Car[] cars = new Car[10];
cars[0] = new Car(); // Populate the first element with a reference to a Car object
cars[0].SomeMethod();
You need to use [] not () when you declaring an array or indexers.
car[] arr = new car[num];
If your requirements doesn't constrain to use only Array, you can use a typed list.
List<Car> = new List<Car>(num);
//num has to be the size of list, but a list size is dinamically increased.
The error in your code is that array should be initialized as follows:
public class factory
{
public factory(int num)
{
car[] arr = new car[num];
}
}
Regards,
using System;
namespace ConsoleApplication1
{
public class Car
{
public double number { get; set; }
public Car()
{
Random r = new Random();
number = r.NextDouble();// NextDouble isn't static and requires an instance
}
}
public class Factory
{
//declare Car[] outside of the constructor
public Car[] arr;
public Factory(int num)
{
arr = new Car[num];
}
}
class Program
{
static void Main(string[] args)
{
Factory f = new Factory(3);
f.arr[0] = new Car();
f.arr[1] = new Car();
f.arr[2] = new Car();
foreach (Car c in f.arr)
{
Console.WriteLine(c.number);
}
Console.Read();
}
}
}

How do I sort an array of custom classes?

I have a class with 2 strings and 1 double (amount).
class Donator
string name
string comment
double amount
Now I have a Array of Donators filled.
How I can sort by Amount?
If you implement IComparable<Donator> You can do it like this:
public class Donator :IComparable<Donator>
{
public string name { get; set; }
public string comment { get; set; }
public double amount { get; set; }
public int CompareTo(Donator other)
{
return amount.CompareTo(other.amount);
}
}
You can then call sort on whatever you want, say:
var donors = new List<Donator>();
//add donors
donors.Sort();
The .Sort() calls the CompareTo() method you implemented for sorting.
There's also the lambda alternative without IComparable<T>:
var donors = new List<Donator>();
//add donors
donors.Sort((a, b) => a.amount.CompareTo(b.amount));
You can also use delegates:
class Program
{
static void Main(string[] args)
{
List<Donor> myDonors = new List<Donor>();
// add stuff to your myDonors list...
myDonors.Sort(delegate(Donor x, Donor y) { return x.amount.CompareTo(y.amount); });
}
}
class Donor
{
public string name;
public string comment;
public double amount;
}
By implementing IComparable and then use Array.Sort.
public class Donator : IComparable {
public string name;
public string comment;
public double amount;
public int CompareTo(object obj) {
// throws invalid cast exception if not of type Donator
Donator otherDonator = (Donator) obj;
return this.amount.CompareTo(otherDonator.amount);
}
}
Donator[] donators; // this is your array
Array.Sort(donators); // after this donators is sorted
I always use the list generic, for example
List<Donator> MyList;
then I call MyList.Sort
MyList.Sort(delegate (Donator a, Donator b) {
if (a.Amount < b.Amount) return -1;
else if (a.Amount > b.Amount) return 1;
else return 0; );
You could use MyArray.OrderBy(n => n.Amount)
providing you have included the System.Linq namespace.
Here is a sort without having to implement an Interface. This is using a Generic List
List<Donator> list = new List<Donator>();
Donator don = new Donator("first", "works", 98.0);
list.Add(don);
don = new Donator("first", "works", 100.0);
list.Add(don);
don = new Donator("middle", "Yay", 101.1);
list.Add(don);
don = new Donator("last", "Last one", 99.9);
list.Add(don);
list.Sort(delegate(Donator d1, Donator d2){ return d1.amount.CompareTo(d2.amount); });
Another way is to create a class that implements IComparer, then there is an overload to pass in the Comparer class.
http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx
This way you could have different classes for each specific sort needed. You could create one to sort by name, amount, or others.

Categories