Could someone please explain to me why the result here is: DVD Unknown DVD:DVD
using System;
class Program
{
class M
{
internal string n;
internal M() { }
internal M(string N)
{
Console.Write(N + " ");
n = N;
}
}
class D : M
{
internal D(string N) : base(N) { n = "DVD:" + N; }
}
static void Main(string[] args)
{
M d1 = new D("DVD");
M m1 = new M("Unknown");
Console.WriteLine(" " + d1.n);
}
}
I understand most parts of the code, except for this line:
internal D(string N) : base(N) { n = "DVD:" + N; }
I know that base calls something from the parent class, but in this case i just don't get it. :/
Let's break apart this line:
internal D(string N) : base(N)
{
n = "DVD:" + N;
}
The part you're most likely needing clarification on is base(N). base(N) is a call to the M(string N) constructor. This happens before the body of this constructor (n = "DVD...) is run.
I think the code will be clearer if you modify what is printed slightly:
class M
{
internal string n;
internal M() { }
internal M(string N)
{
Console.WriteLine("in base " + N);
n = N;
}
}
class D : M
{
internal D(string N) : base(N) { n = "DVD:" + N; }
}
static void Main(string[] args)
{
M d1 = new D("DVD");
M m1 = new M("Unknown");
Console.WriteLine("d1.n is " + d1.n);
}
Outputs
in base DVD
in base Unknown
d1.n is DVD:DVD
The same thing is happening in your output of DVD Unknown DVD:DVD, just all on one line: first, D's constructor calls M's constructor, which writes DVD (this happens before DVD: is added to it). Then, M's constructor is called directly, which writes Unknown. Then, you write d1's n, which is DVD:DVD.
First of all, Console.WriteLine(" " + d1.n); will give you DVD:DVD because base means use the parent class' constructor. So, when you send your parameters into your D class, it is sending your code to your M class, it is executing it which gives you "DVD" on your screen and then it is changing the value of n. After that you are sending the "Unknown" value your M class directly which is not related with your D class anymore and it is showing you "Unknown" on your screen. At the end you are requesting D class' n value which is already "DVD". So the result is DVD Unknown DVD:DVD. I hope this makes sense for you.
Related
This is an extension of this question: Is it possible to dynamically compile and execute C# code fragments?
But is it possible to reference fields, properties and methods of a certain object? For example:
public class SomeClass
{
public int a, b;
public int SomeMethod(int a, int b, int c)
{
return a + b + c;
}
public void Execute()
{
int c = 3;
string code = "a = b = 2; int result = SomeMethod(a, b, c);";
// Compile and execute code here
}
}
The code obviously makes no sense in terms of functionality, but it's just an example.
I wouldn't know a way, but you can call string tmp = Path.GetTempFile() to create a temp file and do a code = "void Main(string[] args){int a = b = 2; int result = SomeMethod(a, b, c); File.WriteAllBytes(\"" + tmp + "\", BitConverter.GetBytes(result));" to save the result. Then you can load it with BitConverter.ToInt32(File.ReadAllBytes(tmp)).
I think you're looking for something like Lambda Expression Serializers
DynamicExpresso
I'm self-learning c# and I'm a little confused on nodes in graph structures. I've cobbled together this code so far, but I have no idea how to remove and entire node from the list:
public class Graph
{
private int _V;
private int _E;
private LinkedList<Int32>[] adj;
public Graph(int V)
{
this._V = V;
adj = new LinkedList<Int32>[_V];
for (int v = 0; v < _V; v++)
{
adj[v] = new LinkedList<Int32>();
}
}
public void AddEdge(int v, int w)
{
_E++;
adj[v].AddFirst(w);
adj[w].AddFirst(v);
}
public void RemoveEdge(int v, int w)
{
_E--;
adj[v].Remove(w);
adj[w].Remove(v);
}
public IEnumerable<Int32> Adj(int v)
{
return adj[v];
}
public int V()
{
return _V;
}
public bool isLeaf(int v)
{
return adj[v].Count() == 1;
}
public int adjacencies(int v)
{
return adj[v].Count();
}
public String toString()
{
StringBuilder s = new StringBuilder();
String NEWLINE = Environment.NewLine;
s.Append(adj[1].Count + NEWLINE);
s.Append(_V + " vertices, " + _E + " edges " + NEWLINE);
for (int v = 0; v < _V; v++) {
s.Append(String.Format("{0:d}: ", v));
foreach (int w in adj[v]) {
s.Append(String.Format("{0:d} ", w));
}
s.Append(NEWLINE);
}
return s.ToString();
}
}
So, if I have four nodes where node 1 has an edge to 2, 2 has edges to both 3 and 4, and 3 and 4 share an edge with each other, I want to remove node 1 completely since it's a leaf. I can remove the edge easily enough, but that node still remains in my list (just without an edge). How do I get rid of 1 completely? I thought I should be able to just do a adj.Remove(1), but that throws an error.
I realize this is probably super easy, but the answers I've looked through in here seem to be describing something different or I'm simply not getting how this works.
Thanks!
Arrays do not support removal. If you really need to encode the concept of "does not exist" into adj, then you could set adj[v] to a value that represents "does not exist". For example,
adj[v] = null.
Alternatively, you could store adjacencies in a Dictionary<Int32>. Instead of
private LinkedList<Int32>[] adj;
you would have
private Dictionary<Int32, LinkedList<Int32>> adj;
and you could remove vertex v by
adj.Remove(v); // don't forget to remove the edges
In either case, you would probably want to update the other methods to handle such "removed" vertices.
Can someone please tell me the program flow and out of the given snippet.I tried this on VS and got 0 0 as output,and i want to know how this works. Thanks.
static void Main(string[] args)
{
Sample s1 = new Sample();
s1.getdata(10, 5.4f);
s1.displaydata();
}
class Sample
{
int i;
Single j;
public void getdata(int i,Single j)
{
i = i;
j = j;
}
public void displaydata()
{
Console.WriteLine(i + " " + j);
}
}
Since the local variables are preferred over the class variables, the class variables are never set. Inside the getdata method you are setting the local (method scoped) variables to their own value. Hence, in the displaydata method, you are printing the default values of the integers (0).
To fix this, you can either change the names of the variables, by prefixing them for example, or use this to set the scope.
public void getdata(int i,Single j)
{
this.i = i;
this.j = j;
}
Writing the code for the mathematical operations between my custom classes of vectors and matrices I have faced a strange (at least for me) problem.
The overloaded operators between types give different results in different places. I have dug out that the result of the operation is sensitive on how the new instance is created inside the "operator +(...)".
I have created the simple code showing the difference (see below).
Two classes are making the same thing and the same result is expected, but in reality not the same.
The overloaded operator of Type2 and the function "test" modify the variable.
I have not found any warning about this in MSDN. This behavior is not marked directly by syntax (f.e. by the "ref" keyword).
Can anyone recommend a link about this problem?
Is it predicted behavior or a mistake in the C# syntax?
using System;
namespace test_operator_overload
{
class Program
{
static void Main()
{
Type1 A1 = new Type1(1);
Console.WriteLine(A1); // 1 - OK
Console.WriteLine(A1 + A1); // 2 - OK
Console.WriteLine(A1); // 1 - OK
Console.WriteLine();
Type2 B1 = new Type2(1);
Console.WriteLine(B1); // 1 - OK
Console.WriteLine(B1 + B1); // 2 - OK
Console.WriteLine(B1); // 2 - Not OK
Console.WriteLine();
Type2 C1 = new Type2(1);
Console.WriteLine(C1); // 1 - OK
Console.WriteLine(test(C1)); // 2 - OK
Console.WriteLine(C1); // 2 - Not OK
}
static Type2 test(Type2 a)
{
a.x += 1;
return a;
}
}
class Type1
{
public double x;
public Type1(double x)
{
this.x = x;
}
public static Type1 operator +(Type1 a, Type1 b)
{
return new Type1(a.x + b.x);
}
public override string ToString() { return GetType().Name + " (" + x + ")"; }
}
class Type2
{
public double x;
public Type2(double x)
{
this.x = x;
}
public static Type2 operator +(Type2 a, Type2 b)
{
a.x += b.x;
return a;
}
public override string ToString() { return GetType().Name + " (" + x + ")"; }
}
}
Your + operator for Type2 is borked, you should not modify the inputs in the operators.
Operators operate on the input by combining the inputs and returning the new results.
I am learning C# for a new position, and to try and understand classes better, I've written a short die-rolling tool to help me. The code essentially rolls four d6, adds the total, and subtracts the smallest die roll. The code is generated through a form, and the form shows all the rolled values, as well as the subtracted for error checking. Here's the code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public static int d1 = 0;
public static int d2 = 0;
public static int d3 = 0;
public static int d4 = 0;
public static int sum = 0;
public Form1()
{
InitializeComponent();
}
private void form_description_Click(object sender, EventArgs e)
{
}
private void roll_button_Click(object sender, EventArgs e)
{
Random random_number = new Random();
d1 = random_number.Next(1, 7);
d2 = random_number.Next(1, 7);
d3 = random_number.Next(1, 7);
d4 = random_number.Next(1, 7);
sum = Math.Min(Math.Min(Math.Min(d1, d2), d3), d4);
label_d1.Text = "Value of D1 is: " + d1;
label_d2.Text = "Value of D2 is: " + d2;
label_d3.Text = "Value of D3 is: " + d3;
label_d4.Text = "Value of D4 is: " + d4;
label_sum.Text = "Value of Sum is: " + sum;
attribute_roll.Text = "Your strength is: " + ((d1 + d2 + d3 + d4) - sum);
}
}
}
The program works, so I know I'm on the right track. The problem I have is converting it into a class. I've tried several times, over and over, and I get different errors everywhere I turn. So for converting this program into a class, my key questions are:
Is it possible to use Random, a pre-existing class, in my own class? Or do I need to declare that in the form itself?
If I use "public static int" in the class, will the values transfer to the method? I've not understood clearly the difference between "public int" and "public static int"?
1. It's possible to use it in your own class, you'd just define it in the class scope.
class Foo
{
Random rng = new Random();
...
}
2. Static members don't require an instance to be accessed, therefore they are global to the entire program, non-static members are tied to an instance.
class Foo
{
public static int Bar = 42;
public int Baz = 42;
}
Console.WriteLine( Foo.Bar ); //OK, static variables don't require the class to be instantiated.
Console.WriteLine( Foo.Baz ); //Error, Baz is not static.
Foo foo_instance = new Foo();
Console.WriteLine( foo_instance.Baz ); //OK
Note that because of this, changing a static variable from inside an instance method will change it globally as well.
class Foo
{
public static int Bar = 42;
public void Baz()
{
Bar = Bar + 1;
}
}
Console.WriteLine( Foo.Bar ); //42
Foo foo_instance = new Foo();
foo_instance.Baz();
Foo foo_instance2 = new Foo();
foo_instance2.Baz();
Console.WriteLine( Foo.Bar ); //44
So the values of your d1, d2, d3, d4, and sum variables can be changed outside the main instance of Form1 if you have multiple instances and cause unexpected results.
The Random class also resides in the System namespace, so if that's giving errors, you need to include using System; at the top of your file.
Let me answer your two questions exactly as you asked them:
1) It is possible to use Randomin your class. It doesn't need to be in the form
2) You can use static variables from static and non-static methods, but you can't use non-static variables from static methods.
Thumbs up! The fact that you found out that classes might help in your situation is the first step to write better rpograms. Try to find a tutorial online which covers the principles of object oriented design. This is something you'll really benefit from, independent of the actual programming language.
My suggestion: invest 50$ for one month of unlimited Pluralsight trainings. Pick a C# fundamentals or C# from scratch course and follow the examples by re-implementing them.
It took a lot of trial and error, but I managed to convert my code into a class. Unfortunately, I'm not 100% sure I understand what I DID. Here's the code for the class:
public class four_d6_less_one
{
////Variables declared here.
public static int dice1;
public static int dice2;
public static int dice3;
public static int dice4;
public static int minus_low;
public static int sum_dice;
//This is the constructor
public four_d6_less_one()
{
Random rand_dice = new Random();
dice1 = rand_dice.Next(1, 7);
dice2 = rand_dice.Next(1, 7);
dice3 = rand_dice.Next(1, 7);
dice4 = rand_dice.Next(1, 7);
minus_low = Math.Min(Math.Min(Math.Min(dice1, dice2), dice3), dice4);
sum_dice = dice1 + dice2 + dice3 + dice4 - minus_low;
}
And here is the code for the form itself:
private void roll_button_Click(object sender, EventArgs e)
{
four_d6_less_one make_it_roll = new four_d6_less_one();
label_d1.Text = "Value of D1 is: " + four_d6_less_one.dice1; //This is where dice1 goes
label_d2.Text = "Value of D2 is: " + four_d6_less_one.dice2; //This is where dice2 goes
label_d3.Text = "Value of D3 is: " + four_d6_less_one.dice3; //This is where dice3 goes
label_d4.Text = "Value of D4 is: " + four_d6_less_one.dice4; //This is where dice4 goes
label_sum.Text = "Value of Sum is: " + four_d6_less_one.minus_low; //This is where minus_sum goes
attribute_roll.Text = "Your strength is: " + four_d6_less_one.sum_dice; //This totals all variables and subtracts minus_sum
}
Here's what I'm not sure I understand:
Why did I have to declare "make_it_roll" to make the code work?
Without that line, the form just displays null values. Is it
because I had to create a new instance of the class to activate it?
Why did I have to call variables by saying "four_d6_less_one.dice1"
and so forth? Why couldn't I just put "dice1" as a variable?
Was there a more efficient way to write this code (I'm sure there always
is, but I'm wondering if I missed something).