When I came across delegates I wrote this really simple program just to practice. when I run it there is a stackoverflowexception. so if anyone can tell me what is wrong with this piece of code please do cause I have wasted a lot of time on trying to make it work but couldn't.
Here is the code:
using System;
public delegate void click();
class test
{
public click flare;
public double length;
public double Length
{
get
{
return Length;
}
set
{
Length = value;
flare();
}
}
}
class glance
{
public glance(ref test a)
{
a.flare = blank;
}
public void blank()
{
Console.WriteLine("this is blank");
}
}
class Program
{enter code here
static void Main(String[] args)
{
test know = new test();
glance x = new glance(ref know);
know.Length = 10;
}
}
It has nothing to do with delegates. You are calling setter method inside of setter in Lenght property and that causes the exception.Use the backing field you created for your property:
public double Length
{
get
{
return length;
}
set
{
length = value;
flare();
}
}
Related
I'm trying to learn get and set and I can't seem to figure out this problem. I have a condition to set a value, only set the value if it's greater than "_num = 10".
My problem is, even if the value is under 10 the value still sets. What am I missing? I should get an error with this code, but I'm not getting it...
thanks for ur time.
using System;
namespace Namespace
{
internal class Program
{
private static void Main(string[] args)
{
int x = Items.Sum = 5;
Console.WriteLine(x);
Console.ReadKey();
}
}
public static class Items
{
private static int _num = 10;
public static int Sum
{
get { return _num; }
set
{
if (value > _num)
_num = value;
}
}
}
}
Because your have property as static and it will be set even before the constructor gets called. That’s why it is returning 10.
Please declare the main method as public not private.
I understand how Auto-Implemented Properties work and how they are supposed to help. I was wondering if I could still use it somehow in a more advanced way.
Imagine I have this:
public int SomeProperty { get; set; }
Which is basically another way of writing the code below (but using Automatic Properties).
private int _someField;
public int SomeProperty
{
get { return _someField;}
set { _someField = value;}
}
What I want to do is write:
private int _someField;
public int SomeProperty
{
get { return _someField;}
set { FunctionA(); _someField = value;}
}
But using the advantages of the Auto-Implemented Properties. Is that possible?
I tried something like this:
public int SomeProperty { get; set{FunctionA();} }
But it doesn't work. Thank you everybody for the help, I know it's silly but I am curious about it.
No, it is not allowed. See the language spec:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#properties
An automatically implemented property (or auto-property for short), is a non-abstract non-extern property with semicolon-only accessor bodies.
I didn't find free tool, but PostSharp handles this. It has trial period and some free-to-use options. Anyway take a look at method decoration and AOP frameworks.
using System;
using PostSharp.Aspects;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var someClass = new SomeClass();
Console.WriteLine($"{nameof(someClass.Value)} = {someClass.Value}");
someClass.Value = 42;
Console.WriteLine($"{nameof(someClass.Value)} = {someClass.Value}");
}
}
class SomeClass
{
public int Value { get; [Decorate] set; }
private void SomeFunction()
{
Console.WriteLine("SomeFunction called");
}
[Serializable, AttributeUsage(AttributeTargets.Method)]
public class DecorateAttribute : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
var target = (SomeClass)args.Instance;
target.SomeFunction();
args.Proceed(); // performs the method it applied to
}
}
}
}
Output:
Value = 0
SomeFunction called
Value = 42
I am a C# teacher and I wrote some automated HW checker for my students.
The students write C# Console Applications. My HW checker is based on input redirection so I can test their code on my own generated input.
The problem is that students sometimes end their program with a Console.ReadKey() instruction (They do so just to make the execution window not close when they ran the program under F5 - Debug). The Console.ReadKey() crashes when ran under input redirection with the following exception:
System.InvalidOperationException: Cannot read keys when either application does not have a console or when console input has been redirected from a file.
Do I have any way to "bypass" this problem (without altering the students code)? Maybe tell Console to ignore ReadKey instructions?
I see a clear case for a Dependency Injection pattern.
Let's build a simple example, with Read, ReadLine and WriteLine functionalities polymorphically: your students must write a homework in which a number given in the Console.ReadLine() must be parsed as int and returned to the Console Window.
Usually a student writes something like:
class Program
{
static void Main(string[] args)
{
var stringValue = Console.ReadLine();
int number;
if (int.TryParse(stringValue, out number))
Console.WriteLine($"The double of {number} is {number * 2}");
else
Console.WriteLine($"Wrong input! '{stringValue}' is not an integer!");
Console.Read();
}
}
Now, instead, create an interface for the Console functionalities:
public interface IOutput
{
void Read();
string ReadLine();
void WriteLine(string text);
}
A student must create a Homework class that wraps all the required homework code, using an IOutput instance in this way:
public class HomeWork
{
private IOutput _output;
public HomeWork(IOutput output)
{
_output = output;
}
public void Run()
{
_output.WriteLine("Give me an integer:");
var stringValue = _output.ReadLine();
int number;
if (int.TryParse(stringValue, out number))
_output.WriteLine($"The double of {number} is {number * 2}");
else
_output.WriteLine($"Wrong input! '{stringValue}' is not an integer!");
_output.Read();
}
}
The Main becomes:
static void Main(string[] args)
{
var h = new HomeWork(new ConsoleOutput());
h.Run();
}
You give them also the ConsoleOutput class:
public class ConsoleOutput : IOutput
{
public void Read()
{
Console.Read();
}
public string ReadLine()
{
return Console.ReadLine();
}
public void WriteLine(string text)
{
Console.WriteLine(text);
}
}
So the use it instead of call directly Console.Read() etc.
The student must pass to you not the entire Application, but only the Homework class.
You can create a test class that use the Homework class with some test implementations of IOutput like the followings:
public abstract class TestOutput : IOutput
{
public TestOutput()
{
Outputs = new List<string>();
}
public void Read()
{
//do nothing?
}
public abstract string ReadLine();
public void WriteLine(string text)
{
Outputs.Add(text);
}
public List<string> Outputs { get; set; }
}
public class TestOutputWithAValidNumber : TestOutput
{
public TestOutputWithAValidNumber(int value)
{
Value = value;
}
public override string ReadLine()
{
return Value.ToString();
}
public int Value { get; }
}
public class TestOutputWithNotValidNumber : TestOutput
{
public TestOutputWithNotValidNumber(string value)
{
Value = value;
}
public override string ReadLine()
{
return Value;
}
public string Value { get; }
}
The test class can be something like this:
[TestClass]
public class TestOutputClass
{
[TestMethod]
public void TestGoodNumber()
{
var testOutput = new TestOutputWithAValidNumber(1234);
var h = new HomeWork(testOutput);
h.Run();
Assert.AreEqual(1234, testOutput.Value);
Assert.AreEqual("Give me an integer:", testOutput.Outputs[0]);
Assert.AreEqual("The double of 1234 is 2468", testOutput.Outputs[1]);
}
[TestMethod]
public void TestWrongNumber()
{
var testOutput = new TestOutputWithNotValidNumber("foo");
var h = new HomeWork(testOutput);
h.Run();
Assert.AreEqual("foo", testOutput.Value);
Assert.AreEqual("Give me an integer:", testOutput.Outputs[0]);
Assert.AreEqual("Wrong input! 'foo' is not an integer!", testOutput.Outputs[1]);
}
}
If you need only to wrap the Console.Read() method, feel free to simplify all this code, but IMHO I thought that a wider view on this possible solution would have been useful anyway.
If the executables are in IL, you can create an easy application that uses ILDASM.
The key point is: disassemble the executable with ILDASM into a text file/stream, look for any call to Console.Read and remove it, than recompile it and run.
I am trying to build a unit test.
The class Position is implemented in a third party library. But for my unit test I need the Size property to be set to a specific value.
public class Position
{
private double _size;
private double Size
{
get
{
return _size;
}
internal set
{
_size = value;
}
}
}
I read this post: How do you create a unit-testing stub for an interface containing a read-only member?
but could not figure out how to make it work for me.
This is the class under test (just a simplified example). The posargument in the CalcPositionMetric() method must be of type Position:
public class PositionMetrics
{
public PositionMetrics()
{}
public double CalcPositionMetric(Position pos)
{
return 2 * pos.Size;
}
}
Here is a piece of my unit test:
using NUnit.Framework;
using NMock;
[TestFixture]
public class PositionUnitTests
{
[Test]
public void TestPosition()
{
Mock<Position> tmpPosMock = mFactory.CreateMock<Position>();
tmpPosMock.Expects.One.GetProperty(v => v.Size).WillReturn(7); /* !!! Exception !!! System.ArgumentException : mock object position has a getter for property Size, but it is not virtual or abstract */
/* Execute Test with tmpPositions*/
PositionMetrics pm = new PositionMetrics();
double result = pm.CalcPositionMetric(tmpPosMock.MockObject)
Assert.AreEqual(14, result);
}
}
But as you can see I get an exception. Could somebody help me to resolve this problem? Any other solutions are also welcome!
Cheers
Konstantin
New answer for the updated question I suggest you to introduce some kind of a proxy interface for that. See the code below:
interface IPosition {
int Size { get; }
}
class Position { //in 3rd party lib
public int Size {
get { return 5; }
}
}
class RealPosition : IPosition { //use this as your real object instead of using Position directly
private Position position;
public RealPosition(Position position) {
this.position = position;
}
public int Size {
get { return position.Size; }
}
}
class MockPosition : IPosition { //use this for testing
public int Size{ get; set; }
}
public class Program {
static void Main(string[] args) {
var pos = new MockPosition { Size = 7 };
Console.WriteLine(Calc(pos)); //prints 14
Console.ReadLine();
}
static int Calc(IPosition pos) { //change your method signature to work with interface
return pos.Size * 2;
}
}
Old answer If the class is not sealed you don't need any mocking libraries. Just use the new modifier for the required properties like this:
class Position {
public int Size { get { return 5; } }
}
class MockPosition : Position {
public new int Size { get; set; }
}
....
var mock= new MockPosition();
mock.Size = 7;
To use these items in some sort of list you'll have to cast them like this:
var items = new List<Position>();
for (int i = 0; i < 5; i++) {
items.Add(new MockPosition { Size = i });
}
foreach (var item in items.Cast<MockPosition>()) {
Console.Write("{0}\t", item.Size); //prints 0 1 2 3 4
}
If it is sealed and the property is not virtual than you'll have to use some other techniques, Moq (which I guess you are using) does not allow that
In my program, I am making currency addition from a for...loop. It is working fine. But I am not sure if what has been done is correct and in accordance with C#.
class Program {
private double _amount;
public double amount {
get {
return _amount;
}
set {
_amount = value;
}
}
static void Main(string[] args) {
Program p = new Program();
for (int i = 1000; i < 1300; i++) {
double y = 30.00;
double x = y + p._amount;
p._amount = x;
}
Console.WriteLine(p._amount.ToString());
Console.ReadLine();
}
}
I have reduced the size of the code. In effect, however, there are several if clauses within the for...loop which I do the calculations.
I would like to thank anyone who could point out any inconsistency with C# coding principles.
The first thing is to use meaningful names, so program could be given a more
meaningful name.
Modularise your code (create a separate class from your program) and use the recommended coding practices by MSDN for C#.
class Calculation
{
public double Amount { get; set; }
public double run(double y)
{
// No need to start at 1000.
for(int i = 0; i < 300; i++)
{
Amount += y;
}
return Amount;
}
}
class Program
{
static void Main(string[] args)
{
Calculation calculation = new Calculation();
// pass your variable as a parameter into a class function.
var y = 30.0;
Console.WriteLine(calculation.run(y).ToString());
// Console.ReadLine(); use control F5 to prevent console window from closing.
}
}
C# Coding Conventions (C# Programming Guide)
I would recommend changing this code:
public double amount
{
get
{
return _amount;
}
set
{
_amount = value;
}
}
with this:
public double getamount()
{
return _amount;
}
public void setamount(int value)
{
_amount = value;
}