This question already has answers here:
Access private fields
(4 answers)
Closed 6 years ago.
I recently had an interview with C# questions. One of them I cannot find an answer to.
I was given a class, looks like this:
public class Stick
{
private int m_iLength;
public int Length
{
get
{
return m_iLength;
}
set
{
if (value > 0)
{
m_iLength = value;
}
}
}
}
Also, a main class was given
static void Main(string[] args)
{
Stick stick = new Stick();
}
The task was to add code to the main that will cause m_iLength in the Stick class to be negative (and it was stressed out that it can be done).
I seem to miss something. The data member is private, and as far as I know the get and set function are by value for type int, so I do not see how this can be done.
Reflection is always the most direct:
var type = typeof(Stick);
var field = type.GetField("m_iLength", BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);
field.SetValue(stick, -1);
Console.WriteLine(stick.Length);
Explanation:
The first line gets the Type object for Stick, so we can get the private fields later on.
The second line gets the field that we want to set by its name. Note that the binding flags are required or field will be null.
And the third line gives the field a negative value.
Related
This question already has answers here:
Print out object elements from list [duplicate]
(2 answers)
Print List of objects to Console
(3 answers)
print list<object> in console c# [duplicate]
(2 answers)
Closed 2 years ago.
I'm learning to code. I have started a little project where I design a text-based RPG.
I am struggling with storing and retrieving objects in and from an array.
Please have a look at my progress so far and tell me what I am doing wrong.
If I am using a wrong approach please also let me know how to do the whole thing smarter :)
First I define some properties of the player:
static class Globals
{
public static string playername;
...
public static object[] playerInventory = new object[4];
}
Then I create the weapon class:
public class Weapon
{
public string weaponName;
public int weaponBaseDamage;
public Weapon(string name, int baseDamage)
{
weaponName = name;
weaponBaseDamage = baseDamage;
}
Then I create the first basic weapon and try to store it in an array.
public class Program
{
public static void Main()
{
Weapon StartSword = new Weapon("My first Sword", 1);
Globals.playerInventory[0] = StartSword;
Console.WriteLine(StartSword.weaponName); // This works
Console.WriteLine(Globals.playerInventory[0]); // This prints "CSharp_Shell.Weapon", but I expected "StartSword"
Console.WriteLine(Globals.playerInventory[0].weaponName); // This results in an Error
The unexpected result of the second WriteLine command tells me that something must be quite wrong, but I don't know what it is and how to fix it. Any advice is welcome! (And please keep in mind that I am new to Coding).
It's required Typecasting. Please try like below:
Console.WriteLine(((Weapon)Globals.playerInventory[0]).weaponName)
Ok, lets look at what your code does:
Weapon StartSword = new Weapon("My first Sword", 1);
Globals.playerInventory[0] = StartSword;
Console.WriteLine(StartSword.weaponName); // This works
Above you create an object of the type Weapon with the name "My first Sword". And then print the name of that public property that is populated in the constructor.
Console.WriteLine(Globals.playerInventory[0]); // This prints "CSharp_Shell.Weapon", but I expected "StartSword"
Here you try to write an object. But an object is not a string so c# will automatically try to convert that to a string and will look at the type. So it is expected that it will not write the properties but a representation of the type.
Console.WriteLine(Globals.playerInventory[0].weaponName); // This results in an Error
Globals.playerInventory is defined as object[] playerInventory, so even if we know that you have entered an object of type weapon there, we need to specify that. Either by letting playerInventory be of the type Weapon[] playerInventory, or by type casting your object before using its properties, like this:
Console.WriteLine(((Weapon)Globals.playerInventory[0]).weaponName);
This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 2 years ago.
I'm trying to open a form from another form. This results in an ArgumentOutOfRangeException.
I think the error is here because I added this lists and my program stopped working:
private static List<string> proxies = ps.proxies;
private static int proxyCounter = 1;
private static string currentProxy = proxies[proxyCounter];
public int TokenTimes = 0;
the lists go to:
class proScanner
{
public List<string> proxies = new List<string>();
public void ScanProxies()
{
var fileText = File.ReadAllLines(#"settings\proxies.txt");
foreach (var s in fileText) proxies.Add(s);
}
}
Debugging can really help you track down your problem, view the values, and solve the problem.
I would guess that your problem is here:
proxyCounter = 1;
currentProxy = proxies[proxyCounter];
And the proxies has less than 2 values (Index starts at zero!).
But some of the reasons why you are having problems tracking down the errors is because you are doing many assignments in the class declaration
private static List<string> proxies = ps.proxies;
private static int proxyCounter = 1;
private static string currentProxy = proxies[proxyCounter];
You should only declare variables and set default values on the class level. Not assign them values from other variables, this should be done inside your class, inside the constructor for example.
You should also look to see if you really need to define all of these statically. I would suggest that you consider a different method.
This question already has answers here:
How to get a property value based on the name
(8 answers)
Closed 3 years ago.
I have a class with is a collection of XPaths. I want to pass the name of the field and want to get the XPath for that field. The problem here is I have to store the passed value in a variable and putting an if condition to check for the corresponding XPath variable as shown below.
As of now, I am using the if condition and I can use switch condition as well but this solution is not feasible as the collection of XPath will grow and it will become unmanageable.
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new Program().IReturnXpath("LastName"));
}
public string IReturnXpath(String nameOfField)
{
if (nameOfField.Equals("Lastname"))
return new XpathCollection().Lastname;
else if (nameOfField.Equals("Firstname"))
return new XpathCollection().Firstname;
else
return "Xpath not found";
}
class XpathCollection
{
public string Lastname = "xpath for lastname";
public string Firstname = "xpath for firstname";
}
}
Let me explain how Microsoft solved exact same problem.
System.Drawing.Color has many properties each reflecting a single color. Color also has a FromName method which allows you to find a color by string parameter. Almost exactly your problem.
As you can see in their, implementation, they create a Hashtable and by using reflection they fill it. Next time someone asks for a color they just lookup and return it. Put generation code in a static constructor and you are done.
https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/ColorConverter.cs,d06a69beb42834b2
This question already has answers here:
Why does Property Set throw StackOverflow exception?
(3 answers)
Closed 6 years ago.
I know, I could simply use abs in this case, but I'm just curious: why is this happening?
public float maxThrotle{
set { maxThrotle = value < 0 ? -value : value; //this line causes problem
}
get { return maxThrotle; }
}
You are causing an infinite loop, by trying to call the property setter from within the property setter.
You probably want to create a private backing field to store the value, as follows:
private float maxThrotle;
public float MaxThrotle {
set { maxThrotle = value < 0 ? -value : value; //this line causes problem
}
get { return maxThrotle; }
}
Note I renamed the property to use a capital letter, in accordance with most C# coding standards.
(Also, the word throttle is spelled with double -t-).
This question already has answers here:
Deep cloning objects
(58 answers)
How do you do a deep copy of an object in .NET? [duplicate]
(10 answers)
Closed 8 years ago.
i basically want to define a templet data object ,
and use this templet data object to assign new data objects.
then put different values to new data objects.
code like:
public class sData
{
public string name;
public int Number;
public sData(string name,int Number)
{
this.poster_path = path;
this.Number = Number;
}
}
sData templet= new sData("aaaa","0");
sData realData1 = new sData();
realData1=templet;
realData1.Number=100;
but after realData1.Number=100;
i found the templet.Number is changed to 100
how can i just give the 100 to realData1 , but no the templet ?
Am I correct in saying that you'd like to setup some a factory object which will create data objects with pre-defined set of values (i.e. a template)?
The code you have above won't do that. You have only created one object but you have two different references to it.
Perhaps something like this will do what you need:
public class sData
{
public string name;
public int Number;
public sData(string name,int Number)
{
this.poster_path = path; //copied from question, this might need updating.
this.Number = Number;
}
sData CreateCopy()
{
return new sData(name, number);
}
}
sData template = new sData("aaaa","0");
sData realData1 = template.CreateCopy();
realData1.Number=100;
This still doesn't feel very elegant, perhaps separate classes for the factory and the data object would be more appropriate, but it's hard to say without more context.
You are assigning the object variable of templet to realData1 and this way you are still referencing the same object in memory:
realData1=templet;
You can assign the values instead of the object itself:
realData1.name = templet.name;
realData1.Number = templet.Number;
Class is of reference type and the reference variables of class sData realData1 and templet point to the same memory location in heap, so the value of templet is getting overwritten by the value realData1.