Accessing attributes within a class and outside of a class - c#

Main method with some tree objects:
namespace Forest
{
class Program
{
static void Main(string[] args)
{
Tree Fir = new Tree();
Fir.species = "Fir";
Fir.height = 100.0;
Fir.trunkDiameter = 10.0;
Tree Oak = new Tree();
Oak.species = "Oak";
Oak.height = 120.0;
Fir.trunkDiameter = 12.5;
}
}
}
A tree class:
namespace Forest
{
class Tree
{
public string species;
public double height;
public double trunkDiameter;
}
}
I want to add an attribute as such: public double trunkCircumference = trunkDiameter * 3.14
But when I do that, the trunkDiameter variable isn't recognized. When adding a static modifier, it fixes, but I cannot access trunkDiameter.
I would just like to add a trunkCircumference attribute.

Since trunkCircumference appears to always return trunkDiameter * 3.14, you could define it as a property, instead of a field.
namespace Forest
{
class Tree
{
public string species;
public double height;
public double trunkDiameter;
public double trunkCircumference
{
get => return trunkDiameter * 3.14;
}
}
}

Related

Variable Values are not getting Updated

I have 3 class files. First is the Main class, second is the Ship class, and the third is the Skill class. All values are added to my Main class file. I have a method where the parameters should be the value in my Main class. Please see below:
public class Skill
{
public double _capInc;
public int bscEng, advEng, expEng;
// engineering
public double capInc(int bsc, int adv, int exp)
{
if(bsc == 5 && adv == 5 && exp == 4)
{
_capInc = 0.48;
}
return _capInc;
}
The values of int bsc, int adv, and int exp should be the value of bscEng, advEng, & expEng which was set in my Main class
skill.bscEng = 5;
skill.advEng = 5;
skill.expEng = 4;
But when I try to run the method in my Ship class, values are different
public class Ship
{
Skill skill = new Skill();
public double capacitor;
public double totalCap()
{
double _totalCap = capacitor * skill.capInc(skill.bscEng, skill.advEng, skill.expEng);
Console.WriteLine(skill.bscEng + " bscEng inside totalCap");
return _totalCap;
}
This is the result when I run my Main class
class MainClass
{
public static void Main (string[] args)
{
Ship ship = new Ship();
Skill skill = new Skill();
skill.bscEng = 5;
skill.advEng = 5;
skill.expEng = 4;
Console.WriteLine(skill.bscEng + " bscEng in Main");
Console.WriteLine(ship.totalCap());
}
}
Result:
5 bscEng in Main
0 bscEg inside totalCap
0
You should assign the values to skill in your ship object.
Example:
ship.skill.bscEng = <yourValue>;
ship.skill.advEng = <yourValue>;
ship.skill.expEng = <yourValue>;
As I said in the comments you need to pass the skill object to the ship object. I've also added an constructor to both classes. I don't know what you really want to do and the code is weird but here's a working solution:
class MainClass
{
public static void Main (string[] args)
{
Skill skill = new Skill(5, 5, 4);
Ship ship = new Ship(skill);
Console.WriteLine(skill.bscEng + " bscEng in Main");
Console.WriteLine(ship.totalCap());
}
}
public class Skill
{
public Skill(int bscEnd, int advEng, int expEng)
{
this.bscEng = bscEnd;
this.advEng = advEng;
this.expEng = expEng;
}
public double _capInc;
public int bscEng, advEng, expEng;
// engineering
public double capInc()
{
if(bscEng == 5 && advEng == 5 && expEng == 4)
{
_capInc = 0.48;
}
return _capInc;
}
}
public class Ship
{
public Ship(Skill skill)
{
Skill = skill;
capacitor = 1.0; // TODO
}
private Skill Skill;
public double capacitor;
public double totalCap()
{
double _totalCap = capacitor * Skill.capInc();
Console.WriteLine(Skill.bscEng + " bscEng inside totalCap");
return _totalCap;
}
}
Output should be:
5 bscEng in Main
5 bscEng inside totalCap
0,48

Calling class method from another class method

From my main code I'm calling a method of a class meth2 which calls another method from another class meth1. It is important for me to respect this structure.
These methods make an assignment of values that are previously defined in the classes but I am not able to get a proper result in my command window (just a 0 instead of a 132). I assume I'm missing something.
Does anybody has an idea? Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace workingWithClasses
{
class meth1
{
public int op1;
public int multiply(int mult)
{
return op1 = 44 * mult;
}
}
class meth2
{
public int CallFuncsClass(int multiplicator)
{
return m1.multiply(int multiplicator);
}
}
class Program
{
static void Main(string[] args)
{
meth1 m1 = new meth1();
meth2 m2 = new meth2();
m2.CallFuncsClass(3);
int result_m1 = m1.op1;
Console.WriteLine(opm1);
Console.ReadKey();
}
}
}
Thanks a lot!
namespace workingWithClasses
{
public class meth1
{
public int op1;
public int multiply(int mult)
{
return op1 = 44 * mult;
}
}
public class meth2
{
meth1 m1 = new meth1();
public int CallFuncsClass(int multiplicator)
{
return m1.multiply( multiplicator);
}
}
class Program
{
static void Main(string[] args)
{
meth2 m2 = new meth2();
int result_m2 = m2.CallFuncsClass(3);
Console.WriteLine(result_m2);
Console.ReadKey();
}
}
}
This code won't compile, right? This line return m1.multiply(int multiplicator); is out of the place. You need to define what is m1. I guess you are looking for dependency injection. You can do this via constructor, so
class meth2
{
private meth1 _m1;
meth2(meth1 m1)
{
if(m1 == null) throw new ... // check input params
_m1 = m1;
}
public int CallFuncsClass(int multiplicator)
{
return _m1.multiply(int multiplicator);
}
}
The usage will be
meth1 m1 = new meth1();
meth2 m2 = new meth2(m1);
m2.CallFuncsClass(3);
Bonus points
Name your classes correctly, instead of meth1 it should be something like Calculator
Don't use public fields: public int op1;. It should be private
Usually you would want your classes to be public, by default the class is internal. In this way you can use it outside a single library
Check parameters for correct value, throw exception if something is incorrect
Make multiply static on class meth1:
public static int multiply(int mult)
Also don't use 'op1', just return the result of the operation.
Call like this:
return meth1.multiply(int multiplicator);
Here is the solution
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace workingWithClasses
{
class meth1
{
public int op1;
public int multiply(int mult)
{
return op1 = 44 * mult;
}
}
class meth2
{
public int CallFuncsClass(int multiplicator)
{
meth1 m1=new meth1();
return m1.multiply(multiplicator);
}
}
class Program
{
static void Main(string[] args)
{
meth2 m2 = new meth2();
int result_m1=m2.CallFuncsClass(3);
Console.WriteLine(result_m1);
Console.ReadKey();
}
}
}
If you want to call methods from meth1 from within meth2 like that (without creating an object of type meth1) you need to make multiply() static.
This will allow it to be used in the manner you're using:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace workingWithClasses
{
class meth1
{
//note statics
static int op1;
static int multiply(int mult)
{
return op1 = 44 * mult;
}
}
class meth2
{
public int CallFuncsClass(int multiplicator)
{
//access to multiply() is valid here
return meth1.multiply(multiplicator);
}
}
class Program
{
static void Main(string[] args)
{
meth1 m1 = new meth1();
meth2 m2 = new meth2();
m2.CallFuncsClass(3);
int result_m1 = m1.op1;
Console.WriteLine(opm1);
Console.ReadKey();
}
}
}

Float enum and aggregate class

I have to create walet class, where i count how many coins it has, so:
enum Coins {
OneCent = 0.01f,
FiveCent = 0.05f,
OneDollar = 1.0f
}
and:
public class RowQuantity<T> {
public T entity;
public int Quantity;
}
and my walet:
public class Walet {
public List<RowQuantity<Coins>> CoinsCash;
public Walet() {
this.CoinsCash.Add(new RowQuantity<Coins> { entity = Coins.OneCent, Quantity = 25 });
}
}
The problem goes here:
I can't have enum with float value => so, i have to declare it as a static class.
public static class Coins {
public const float OneCent = 0.01f;
public const float FiveCent = 0.05f;
public const float OneDollar = 1.0f;
}
But in this way, i can't pass static type as instance of generic class.
So, how could i realise this? (List with quantity of float enum values)
First of all, to avoid rounding issues, you need to use decimal. Secondly, you need to make it an instance class that shows some static properties that are OneCent, FiveCent and OneDollar, like so:
public sealed class Coins
{
private decimal _num;
private Coins(decimal num)
{
_num = num;
}
public static readonly Coins OneCent = new Coins(0.01M);
public static readonly Coins FiveCent = new Coins(0.05M);
public static readonly Coins OneDollar = new Coins(1M);
//add more properties like this
}

Creating a generic list of objects in C#

By way of an intro, I'm creating a basic Quadtree engine for personal learning purposes. I'm wanting this engine to have the capability of working with many different types of shapes (at the moment I'm going with circles and squares) that will all move around in a window and perform some sort of action when collision occurs.
Here are my shape objects as I have them so far:
public class QShape {
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape {
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour) {
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape {
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
Now my question is, how do I create a generic list (List<T> QObjectList = new List<T>();) in C# so I can have one list containing all these various shapes that may have different properties (e.g., QCircle has the "radius" property while QSquare has the "sideLength" property)? An example of implementation would be helpful as well.
I just know that there is a stupidly obvious answer to this question but I'd appreciate any help anyway. I'm trying to get back into C#; it has obviously been a while...
You need to use downcasting
Store the objects in a list with the base class
List<QShape> shapes = new List<QShape>
You can then upcast the object safely if you know what it is e.g.
if(shapes[0] is QSquare)
{
QSquare square = (QSquare)shapes[0]
}
You can also implicitly downcast objects
QSquare square = new Square(5,0,0,"Blue");
QShape shape = square
For more information read the Upcasting and Downcasting sections here
You should implement an Interface. For example
public interface IHasLength
{
int Length;
}
Then in the implementation you can do
public class QSquare : QShape, IHasLength {
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
public int Length { get { return sideLength; } }
}
public class QCircle : QShape, IHasLength {
public int radius;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
public int Length { get { return radius; } }
}
FInally, in your list:
List<IHasLength> shapesWithSomeLength = new List<IHasLength>();
Now your list can hold ANYTHING that implements IHasLength whether it's a QCircle, QShape, or even a QDuck if you want as long as it implements IHasLength.
Is this what you want?
public class QShape
{
protected QShape() { }
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape
{
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour)
{
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape
{
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour)
{
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
class Program
{
static void Main(string[] args)
{
List<QShape> list = new List<QShape>();
list.Add(new QCircle(100, 50, 50, "Red"));
list.Add(new QCircle(100, 400, 400, "Red"));
list.Add(new QSquare(50, 300, 100, "Blue"));
foreach (var item in list.OfType<QCircle>())
{
item.radius += 10;
}
foreach (var item in list.OfType<QSquare>())
{
item.sideLength += 10;
}
}
}
You could store them in a List<QShape> but this would mean that you could not access type-specific properties.
Generally, you might approach this by providing a common interface in your base class, and overriding behaviour in subclasses. In this way, a common interface can hide a diverse bunch of behaviours. For instance a Grow method could hide the complexities of growing items of different shape and could be called without explicit knowlege of the shape upon which it is operating.
public abstract class QShape {
public abstract void Grow(int amt);
}
public class QSquare : QShape {
private int sideLength;
public override void Grow(int amt)
{
sideLength+=amt;
}
}
public class QCircle : QShape {
private int radius;
public override void Grow(int amt)
{
radius+=amt;
}
}
I feel like i'm missing something but...
List<QCircle> circleObjects = new List<QCircle>();
and
List<QSquare> squareObjects = new List<QSquare>();
will work perfectly well.
EDIT:
Ah, I didn't understand what was being asked.
Yes, as your QCircle and QSquare classes inherit from QShape, you can just do.
List<QShape> shapes= new List<QShape>();
It's worth noting that if you want to access the radius property of all the QCircle's in that list, then you are going to have to filter the list based on type.
You can use Ian Mercer's comment List<QShape>
And here's how you would fill it:
List<QShape> shapes = new List<QShape>();
QCircle circle = new QCircle();
shapes.Add(circle);
To unbox it:
QCircle circle = (QCircle) shapes[0];
If you need to call a method off the base class, no need to unbox, just use it.
Storing
You're already on the right track with your class definitions. What you have to do is make a List of the superclass (in this case, QShape), which will be able to hold all of your shapes.
Here's an example of how you would make it:
List<QShape> objects = new List<QShape>();
objects.add(new QCircle(...));
objects.add(new QSquare(...));
Accessing
The problem here is differentiating what is what once everything is in the list. That's done with the getType() and typeof() methods of C#. (Jon Skeet has an excellent answer about how to do this). Basically, it looks like this:
if(objects.get(some_position).getType() == typeof(QCircle))
QCircle circle = objects.get(some_position);
else if(/* like above with QSquare */)
QSquare square = objects.get(some_position);
After you do this, you can resume using your objects like normal. But if you try accessing them from the list, you can only use the methods and variables that QShape has, as every object put in the list will be cast to it.
public Class abstract Base<T>
{
public abstract List<T>GetList();
}
then do this
public class className:Base<ObjectName>
{
public override List<T>GetList()
{
//do work here
}
}

Understanding Google V8's Architecture

I'm not sure I understand V8's architecture (yes, I've read its documentation).
In C# with the v8sharp wrapper I write something like this, for example:
namespace App
{
class Point
{
public Point() { }
public Point(double x, double y) {
this.X = x;
this.Y = y;
}
public double X { get; set; }
public double Y { get; set; }
}
}
static class Program
{
static void Main() {
//registering with v8sharp
V8Engine engine = V8Engine.Create();
engine.Register<App.Point>();
//execute javascript
object rtn = engine.Execute("new App.Point(10, 10);");
}
}
How would I write the same thing in Standard C++ without this wrapper?
Thanks.
If you look here: http://code.google.com/apis/v8/embed.html they have a sample that is identical to yours under "Accessing Dynamic Variables"

Categories

Resources