Skip to content

Instantly share code, notes, and snippets.

@bbrt3
Last active August 10, 2021 19:02
Show Gist options
  • Save bbrt3/cf11ebef9dbbb63d9060a724d8d11aae to your computer and use it in GitHub Desktop.
Save bbrt3/cf11ebef9dbbb63d9060a724d8d11aae to your computer and use it in GitHub Desktop.
C#
// FASTER THAN INTERFACES, BECAUSE EVERYTHING IS IN ONE PLACE!
public abstract class AbstractWorker
{
// CONST, FIELDS, PROPERTIES ALLOWED!
const int salaryMultiplier = 1;
protected int Salary { get; set; }
private IWorker _worker;
public constructor(IWorker worker, int baseSalary)
{
_worker = worker;
Salary = salaryMultiplier * baseSalary;
}
public abstract void StartWork();
public abstract void StopWork();
public abstract void Break();
// STATIC MEMBERS ALLOWED!
// ALL ACCESS MODIFIERS ARE WELCOME!!
// ALSO THERE'S DECLARATION+DEFINITION INSIDE!!
protected static void GenerateExtraPay(int value)
{
Salary += salaryMultiplier * value;
}
}
public class Worker1 : AbstractWorker // ONLY SINGLE INHERITANCE ALLOWED!!!
{
// ONLY PARTIALLY IMPLEMENTED AND THATS COOL!
public override void StartWork()
{
System.Console.WriteLine("IM WORKING!");
}
}
/*
IT IS DYNAMIC ARRAY!!!
ArrayList is a non-generic collection of OBJECTS
whose size increases dynamically
It is the same as array except that its size increases dynamically (vector)
- accepts OBJECT type, so we may put everything we want here
Since everything derives from object type then we can put everything here
But if it is some variable with value type then we have to convert it to object
- NULLs and duplicates are allowed
*/
var arrList = new ArrayList();
arrList.Add(16);
arrList.Add("A");
arrList.Add(1414.55541412);
foreach (elem in arrList)
{
System.Console.WriteLine(elem.ToString());
}
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing
/*
VALUE TYPES can be assigned a value directly.
They are derived from the class System.ValueType.
The value types directly contain data.
Those are stored in the stack.
REFERENCE TYPES do not contain the actual data stored in a variable,
but they contain a reference to the variables.
They refer to a memory location.
If they data in the memory location is changed by one of the variables,
the other variable automatically reflects the change in value.
Built-in reference types: object, dynamic, string.
OBJECT TYPE
It is the ultimate base class for all data types in C# Common Type System (CTS).
Object is an alias for System.Object class.
The object types can be assigned values of any other types.
However, before assigning values, it needs type conversion.
When a value is converted to object type, it is called boxing.
When an object value is converted to a value type it is called unboxing.
Type checking for these types of variables takes place at compile time.
DYNAMIC TYPE
You can store any type of value in the dynamic data type variable.
Type checking for these types of variables takes place at runtime.
There are also pointer types!!
*/
/*
1. == COMPARES OBJECT REFERENCES
2. .Equals() compares object contents
3. String datatypes always does content comparsion
*/
// REFERENCE // CONTENT
object o = "== vs .Equals()";
object o1 = o;
// TRUE
// Because o1 is referencing o
System.Console.WriteLine(o == o1);
// TRUE
System.Console.WriteLine(o.Equals(o1));
string o2 = new string("== vs .Equals()".ToCharrArray());
// TRUE
// STRING ALWAYS DOES CONTENT COMPARSION!!!
System.Console.WriteLine(o1 == o2);
// TRUE
// SAME VALUE CONTENT
System.Console.WriteLine(o1.Equals(o2));
public interface IWorker
{
// ONLY METHOD DECLARATIONS
// NO DEFINITIONS
// CAN ONLY CONTAIN METHODS
public void StartWork();
public void StopWork();
public void Break();
// NO CONSTRUCTORS
// NO STATIC MEMBERS
// ONLY PUBLIC MODIFIER (dom publiczny)
// SLOW BECAUSE IT HAS TO FIND THE METHOD DEFINITOINS IN IMPLEMENTATIONS!!
}
class Example: IWorker, IWorker2, IWorker3
{
// MULTIPLE INHERITANCE ALLOWED
// IT SHOULD BE FULLY IMPLEMENTED
}
/*
MUTABLE
- CAN CHANGE
- NOT THREAD-SAFE
Examples of mutbale objets:
- master data (things that once set won't change, ex. country)
- configuration data
- singleton objects
IMMUTABLE
- CANNOT CHANGE ONCE SET (EXTERNAL OR INTERNAL CHANGE)
- THREAD-SAFE
- GOOD FOR KEYS IN HASHMAPS
- USED IN CACHING
*/
// mutable object
class Currency
{
private string _CurrencyName;
public string CurrencyName
{
get { return _CurrencyName; }
set { _CurrencyName = value; }
}
private string _CountryName;
public string CountryName
{
get { return _CountryName; }
set { _CountryName = value; }
}
}
// immutable class
// 1. Remove setters
// 2. Create a constructor to pass data
// 3. Make the variables readonly (NO INTERNAL CHANGES!)
class Currency
{
public Currency(string CurrencyName)
{
_CurrencyName = CurrencyName;
}
private readonly string _CurrencyName;
public string CurrencyName
{
get { return _CurrencyName; }
// set { _CurrencyName = value; }
}
}
class Example
{
// FIELD
// It is private to your class and stores the actual data
private int _myField;
// PROPERTY
// When accesssed it uses the underlying field
// But it doesn't expose it directly
public int MyProperty
{
get
{
return _myField;
}
set
{
_myField = value;
}
}
// AUTO-PROPERTY (C#)
// It auto generates underlying field and logic to access it
// for us, but we should remember what happens underneath!
public int AnotherProperty { get; set; }
}
/*
Primitive types are stored on the stack.
Objects types are stored on the heap.
Pointers to object types are stored on the stack.
NEW KEYWORD MEANS HEAP IS BEING USED
BUT REFERENCE TO THAT HEAP OBJECT (POINTER) IS ALSO BEING CREATED AT STACK
CLASS IS STORED ON THE HEAP.
WHEN WE USE STRUCT INSTEAD OF CLASS
THEN OBJECTS ARE STORED INDIVIDUALLY
SO CHANGE IN ONE REFERENCING OTHER
WON'T AFFECT THE SECOND ONE!!!
CLASS IS PASSED AS REFERENCE
PRIMITIVE VALUES ARE PASSED AS VALUE
STACK (REFERENCES):
bool, byte, char, decimal, double, enum, float, int,
long, sbyte, short, struct, uint, ulong, ushort
also references to the objects AND STRUCTS!
- static memory allocation
- variables cannot be resized
- fast access
- visible to parent thread
- can only be used by method executing
HEAP (CONTENTS):
class, interface, delegate, object, string
- dynamic memory allocation
- variables can be resized
- slow access
- visible to all threads
- can be used inside whole application
*/
// variable gets created on stack
int score = 5;
// copy of value has been made and created on stack too
int score2 = score;
// score2 variable changes its value to 97
// since we are working on stack memory
// score value is still the same
// but score2 value changed
score2 = 97;
class Report
{
public Title { get; set; }
public Description { get; set; }
}
// Object is created on heap
// reference to that object is created on stack (pointer)
Report rep1 = new Report
{
Title = "a",
Description = "a"
}
// Object is created on heap
// reference to that SAME OBJECT is created on stack (pointer)
Report rep2 = rep1;
// WE OVERWRITE BOTH REPORTS THIS WAY!!!
rep2.Title = "f";
/*
PROBLEM:
Adding new content to existing string
*/
string a = "fafa";
/* It looks like we are just adding new content to existing string
but what really happens is new longer string object is being created
This is because strings are immutable objects.
Once we set their value, we cannot change it directly in that object
Well we can, but new object is being created
Every append operation like this is O(n^2)
*/
a += "rafa";
/*
Alternative solution to just using strings would be using STRINGBUILDER.
It is being used to represent mutable string of characters.
We get buffer of fixed size and we can append stuff all we want
without actually creating new obejcts each time (MUCH FASTER)!
*/
// string, capacity
StringBuilder sb = new StringBuilder("fafa", 25);
sb.append("rafa");
System.Console.WriteLine(sb.Capacity);
System.Console.WriteLine(sb.ToString());
/*
There is a few ways we can convert types in C#.
*/
// 1. Built-in methods
int a = 16;
double b = Convert.ToDouble(a);
string c = a.ToString();
// 2. Casting
int a = 10;
double b = (int)a;
decimal c = (decimal)b;
[TestFixture]
public class EventConfigControllerUnitTests
{
private Mock<IEventConfigService> _service;
private EventConfigController _controller;
[SetUp]
public void Setup()
{
_service = new Mock<IEventConfigService>();
_controller = new EventConfigController(_service.Object);
}
[Test]
public void GetAllEvents_WhenNoEventsInService_ShouldReturnEmptyListOfEvents()
{
//Arrange
_service.Setup(s => s.GetAll())
.Returns(new List<EventConfigDTO>());
//Act
var result = _controller.GetAll();
var okResult = result as OkObjectResult;
//Assert
Assert.IsNotNull(okResult);
Assert.AreEqual(200, okResult.StatusCode);
Assert.IsInstanceOf<IEnumerable<EventConfigDTO>>(okResult.Value);
Assert.IsEmpty(okResult.Value as IEnumerable<EventConfigDTO>);
}
[Test]
public void PostEvent_ValidModel_ShouldReturnOK()
{
//Arrange
_service.Setup(s => s.Post(It.IsAny<EventConfigDTO>()));
//Act
var eventConfig = new EventConfigDTO
{
EventName = "Test",
ProductName = "Test",
EventAction = "Test",
ProductVersion = "Test"
};
var result = _controller.Post(eventConfig);
var okResult = result as OkObjectResult;
//Assert
Assert.IsNotNull(okResult);
Assert.AreEqual(200, okResult.StatusCode);
}
[Test]
public void PostEvent_IsInvalidModel_ShouldReturn400()
{
//Arrange
_service.Setup(s => s.Post(It.IsAny<EventConfigDTO>()));
_controller.ModelState.AddModelError("ProductVersion", "This field is required.");
//Act
var eventConfig = new EventConfigDTO
{
EventName = "Test",
ProductName = "Test",
EventAction = "Test"
};
var result = _controller.Post(eventConfig);
var badRequestResult = result as BadRequestObjectResult;
//Assert
Assert.IsNotNull(badRequestResult);
Assert.AreEqual(400, badRequestResult.StatusCode);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment