I am still learning basics of C# and found this unfinished class task that really confused me. To me, it looks like a class that is supposed to have a generic Stack's methods, constructors, and its property. But that hardly makes sense to me.
I know generic stacks are collections, but I don't know how to approach making a class similar to it or maybe it's about making a class that acts like a Stack class, I am honestly not sure.
The big thing that confused me was the parameterless methods and constructors, how would one even go about making them work if they are supposed to be parameterless?
I know from documentation that generic StackT has all of these methods, constructors and a property, but I have no idea how to implement them in this class and in this manner. How would one even pass anything to this class?
Please help make sense of it.
using System;
using System.Collections;
using System.Collections.Generic;
namespace GenericStackTask
{
/// Represents stack of the specified type T.
/// <typeparam name="T">Specifies the type of elements in the stack.</typeparam>
public class Stack<T> : IEnumerable<T>
{
/// Initializes a new instance of the stack class that is empty and has the default initial capacity.
private Stack _stack;
public Stack()
{
Stack myStack = new Stack();
}
/// Initializes a new instance of the stack class that is empty and has
/// the specified initial capacity.
/// <param name="capacity">The initial number of elements of stack.</param>
public Stack(int capacity)
{
Stack myStack = new Stack(capacity);
_stack = myStack;
_count = capacity;
}
/// Initializes a new instance of the stack class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
/// <param name="collection">The collection to copy elements from.</param>
public Stack(IEnumerable<T> collection)
{
Stack mystack =
_stack = mystack;
}
/// Gets the number of elements contained in the stack.
public int Count => throw new NotImplementedException();
/// Removes and returns the object at the top of the stack.
/// <returns>The object removed from the top of the stack.</returns>
public T Pop()
{
new Stack(_stack);
throw new NotImplementedException();
}
/// Returns the object at the top of the stack without removing it.
/// <returns>The object at the top of the stack.</returns>
public T Peek()
{
throw new NotImplementedException();
}
/// Inserts an object at the top of the stack.
/// <param name="item">The object to push onto the stack.
/// The value can be null for reference types.</param>
public void Push(T item)
{
throw new NotImplementedException();
}
/// Copies the elements of stack to a new array.
/// <returns>A new array containing copies of the elements of the stack
public T[] ToArray()
{
throw new NotImplementedException();
}
/// Determines whether an element is in the stack.
/// <param name="item">The object to locate in the stack. The value can be null for reference types.</param>
/// <returns>Return true if item is found in the stack; otherwise, false.
public bool Contains(T item)
{
throw new NotImplementedException();
}
/// <summary>
/// Removes all objects from the stack.
/// </summary>
public void Clear()
{
throw new NotImplementedException();
}
/// Returns an enumerator for the stack.
/// <returns>Return Enumerator object for the stack.</returns>
public IEnumerator<T> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
}
Related
I have implemented some sort of LINQ Range operator and do want to have a test which will verify that the Range operator is actually deferred.
My Range operator methods:
/// <summary>
/// The Range static method, validation part.
/// </summary>
/// <param name="start">The start.</param>
/// <param name="count">The count.</param>
/// <returns></returns>
public static IEnumerable<int> Range(int start, int count)
{
long max = ((long) start) + count - 1;
if (count < 0 || max > Int32.MaxValue) throw new ArgumentOutOfRangeException(nameof(count));
return RangeIterator(start, count);
}
/// <summary>
/// The Range operator iterator.
/// </summary>
/// <param name="start">The start.</param>
/// <param name="count">The count.</param>
/// <returns></returns>
static IEnumerable<int> RangeIterator(int start, int count)
{
for (int i = 0; i < count; ++i)
{
yield return start + i;
}
}
For the other deferred operators I have created ThrowingExceptionEnumerable utility class, which helps with testing:
/// <summary>
/// The class responsible for verifying that linq operator is deferred.
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class ThrowingExceptionEnumerable<T> : IEnumerable<T>
{
/// <summary>
/// The methods throws <see cref="InvalidOperationException"/>.
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
throw new InvalidOperationException();
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// The method which checks that the given <see cref="deferredFunction"/> actually uses deferred execution.
/// When the function just call itself it should not throw an exception. But, when using the result
/// by calling <see cref="GetEnumerator"/> and than GetNext() methods should throws the <see cref="InvalidOperationException"/>.
/// </summary>
/// <typeparam name="TSource">The deferred function source type.</typeparam>
/// <typeparam name="TResult">The deferred function result type.</typeparam>
/// <param name="deferredFunction">The deferred function (unit of work under the test).</param>
public static void AssertDeferred<TSource,TResult>(
Func<IEnumerable<TSource>, IEnumerable<TResult>> deferredFunction)
{
var source = new ThrowingExceptionEnumerable<TSource>();
// Does not throw any exception here, because GetEnumerator() method is not yet used.
var result = deferredFunction(source);
// Does not throw InvalidOperationException even here, despite the fact that we retrieve the enumerator.
using var iterator = result.GetEnumerator();
Assert.Throws<InvalidOperationException>(() => iterator.MoveNext());
}
And for instance deferred Select operator has the following test:
/// <summary>
/// Should check that Select operator is deferred.
/// </summary>
[Fact]
public void VerifySelectExecutionIsDeferred()
{
ThrowingExceptionEnumerable<int>.AssertDeferred<int, int>(source => source.Select(x => x));
}
The first problem I have faced during writing such unit test for the Range operator is that Range is actually a static method and not an extension method. Also the thing is, that Range signature does not have a source parameter, so the same approach can not be used.
Do you have some clever ideas, how it can be tested?
External code isn't going to be able to do anything to verify that the values are generated on the fly. The only actual difference between a method like this and one that materializes a collection and returns it is the memory footprint at scale, which is quite difficult to reliably test in a unit test.
You can clearly tell that it doesn't do that my looking at the code, but you'd need to alter the implementation in some pretty significant way to end up with something that would allow you to verify that in a unit test (such as writing a more generalized "Generate" method that used a delegate to generate the next value).
If you had some sort of hard requirement that your implementation has unit tests to verify such things, I'd write such a Generate method, implement your Range method by calling Generate, write a unit test to verify that Generate doesn't call the delegate until generating the next value in the sequence, and then assert that the Range method defers execution because it uses Generate to produce its sequence. I wouldn't want to do this in production code though, this would really be just a way of meeting the requirement and making some sacrifices in readability and (mild) performance for the sake of it.
In a system we are dependent on a third party service and once every minute we download data from them and update our data. It is related to E-signing so it is a lot of fields to update. Right now we are getting all the information and then we do an update on our side even if nothing has changed.
My thought was to do a deep copy using any of the methods shown below and then compare the values. However since there are so many variables I wonder if there is someway I can compare all values and see if they are equal and not have to write code to check each variable? An agreement as shown below have both value and reference types.
public class Agreement
{
//Properties here, both value and reference types
public bool HasChanged(Agreement oldagreement)
{
//Code here
}
}
Method example:
var oldagreement = agreement.Clone();
var document = client.GetThirdPartyAgreement(agreement.AgreementDocumentId);
UpdateDocument(agreement, document);
if(agreement.HasChanged(oldagreement)
{
agreementRepository.Update(agreement);
}
Deep copy extension methods:
/// <summary>
/// Perform a deep Copy of the object, using Json as a serialisation method. NOTE: Private members are not cloned using this method.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T CloneJson<T>(this T source)
{
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
// initialize inner objects individually
// for example in default constructor some list property initialized with some values,
// but in 'source' these items are cleaned -
// without ObjectCreationHandling.Replace default constructor values will be added to result
var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T Clone<T>(this T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
I got it to work using the tip from #LasseV.Karlsen. One problem I had was DateTimes however. When I compared the DateTime object in C# they were equal but when the metod Newtonsoft.Json.JsonConvert.SerializeObject() was called they generated a different time string. These were the strings generated 2016-10-21T10:42:09+02:00 and 2016-10-21T10:42:09.
I solved this by extending Newtonsoft.Json.Converters.IsoDateTimeConverter like the code below. Afterwards all DateTime objects had the same format.
public class CustomDateTimeConverter : IsoDateTimeConverter
{
public CustomDateTimeConverter()
{
base.DateTimeFormat = "yyyy-MM-ddTHH:mm:sszzz";
}
}
Working method example:
//CloneJson is the extension method from above - Deep copy
var oldAgreement = agreement.CloneJson();
var document = client.GetThirdPartyAgreement(agreement.AgreementDocumentId);
UpdateDocument(agreement, document);
var agreementString = Newtonsoft.Json.JsonConvert.SerializeObject(agreement, new CustomDateTimeConverter());
var oldAgreementString = Newtonsoft.Json.JsonConvert.SerializeObject(oldAgreement, new CustomDateTimeConverter());
if (agreementString != oldAgreementString)
{
agreementRepository.Update(agreement);
}
I have a Dictionary containing strings as keys, and objects as values in an abstract class.
I have two classes deriving from this abstract class.
One of the deriving classes works perfectly, all configurations and items are loaded and retrievable without issues.
However, the other class is giving me headaches.
When I try to get an object of type "Domain"; I get an invalid cast exception, although I am adding the value to the dictionary as said type.
Here is the code:
public sealed class UserDomainConfig: ConfigParser {
public UserDomainConfig(string configFilePath) : base(configFilePath) { }
public Domain GetConfig(string key) => GetConfig<Domain>(key);
public override bool LoadConfigs() {
return base.LoadConfigs();
}
public UserDomainConfig SetConfig(string key, Domain value) {
base.SetConfig(key, value);
return this;
}
}
public abstract class ConfigParser: IConfig {
/* Snip */
/// <summary>
/// Gets the config.
/// </summary>
/// <returns>The config.</returns>
/// <param name="key">Key.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public virtual T GetConfig<T>(string key) {
object output = null;
try {
if (!configs.TryGetValue(key, out output))
return default(T);
//return (T)output;
//return output as T;
// This is where the exception is occurring.
// I've tried multiple solutions to try to remedy this issue.
return (T)Convert.ChangeType(output, typeof(T));
} catch (InvalidCastException ex) {
logger.Error($"Failed to cast config { key }!");
}
return default(T);
}
/// <summary>
/// Sets the config.
/// </summary>
/// <returns>The config.</returns>
/// <param name="key">Key.</param>
/// <param name="value">Value.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public virtual IConfig SetConfig<T>(string key, T value) {
if (KeyExists(key))
configs.Remove(key);
configs.Add(key, value);
return this;
}
Any ideas on how to fix this, and/or why this isn't working in the first place, although it works like a charm with strings, bools, and ints?
The Convert class only supports simple types, known by .NET, like Int32, String, DateTime. It does not support user defined or complex types like Domain. If you try to convert something to a not-supported type, the method Convert.ChangeType throws an InvalidCastException. The only exception is that it will work if the Original value (output) is already of that desired type; than no actual conversion is needed.
For more information, read: https://msdn.microsoft.com/en-us/library/dtb69x08(v=vs.110).aspx
If you are certain the stored value is of the type Domain, than log more information. Something like this:
logger.Error($"Failed to cast config { key } of type { output.GetType() } to type { typeof(T) }!");
This way you can verify your claim that both types are the same.
I have the following Class which inherits IEnumerable
public class LinesEnumerable : IEnumerable<Point>
{
protected readonly IPointSeries _pointSeries;
protected readonly ICoordinateCalculator<double> _xCoordinateCalculator;
protected readonly ICoordinateCalculator<double> _yCoordinateCalculator;
protected readonly bool _isDigitalLine;
/// <summary>
/// Initializes a new instance of the <see cref="LinesEnumerable" /> class.
/// </summary>
/// <param name="pointSeries">The point series.</param>
/// <param name="xCoordinateCalculator">The x coordinate calculator.</param>
/// <param name="yCoordinateCalculator">The y coordinate calculator.</param>
/// <param name="isDigitalLine">if set to <c>true</c> return a digital line .</param>
public LinesEnumerable(IPointSeries pointSeries, ICoordinateCalculator<double> xCoordinateCalculator, ICoordinateCalculator<double> yCoordinateCalculator, bool isDigitalLine)
{
_pointSeries = pointSeries;
_xCoordinateCalculator = xCoordinateCalculator;
_yCoordinateCalculator = yCoordinateCalculator;
_isDigitalLine = isDigitalLine;
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
/// </returns>
public virtual IEnumerator<Point> GetEnumerator()
{
return _isDigitalLine ?
(IEnumerator<Point>)new DigitalLinesIterator(_pointSeries, _xCoordinateCalculator, _yCoordinateCalculator) :
new LinesIterator(_pointSeries, _xCoordinateCalculator, _yCoordinateCalculator);
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
However, when I try to do the following:
linesEnumerable = linesEnumerable.Concat(new[] { new Point(viewportWidth, lastYCoordinate) });
it says 'System.Collections.IEnumerable' does not contain a definition for 'Concat' and the best extension method overload 'System.Linq.Queryable.Concat(System.Linq.IQueryable, System.Collections.Generic.IEnumerable)' has some invalid arguments
I already have System.Linq namespace added
Anybody know why this is happening?
The compiler will give this error when the two collections are of different types T. For example:
List<int> l1 = new List<int>();
List<string> l2 = new List<string>();
var l3 = l1.Concat(l2);
var l4 = l1.Union(l2);
The Concat and Union calls will result in the following compile-time errors respectively:
'List' does not contain a definition for 'Concat' and the best extension method overload 'Queryable.Concat(IQueryable, IEnumerable)' requires a receiver of type 'IQueryable'
'List' does not contain a definition for 'Union' and the best extension method overload 'Queryable.Union(IQueryable, IEnumerable)' requires a receiver of type 'IQueryable'
It is confusing because the message is misleading and VS intellisense recognizes the extension methods. The solution is that l1 and l2 must be lists of the same type T.
Well this won't help you but this question is the top result when you google the error so I'm going to say what my problem was.
I had the following classes:
class Group
class Row : Group
class Column : Group
I was trying to call Concat on an IEnumerable<Row> with an IEnumerable<Column> to get an IEnumerable<Group>. This doesn't work because you can't convert the columns to rows. The solution was to cast my IEnumerable<Row> to IEnumerable<Group>.
e.g. rows.Cast<Group>().Concat(columns)
I'm creating an extension method for MultiValueDictionary to encapsulate frequent ContainsKey checks and I was wondering what was the best way to create an empty IReadOnlyCollection?.
What I've used so far is new List<TValue>(0).AsReadOnly() but there must be a better way, an equivilant to IEnumerable's Enumerable.Empty
public static IReadOnlyCollection<TValue> GetValuesOrEmpty<TKey, TValue>(this MultiValueDictionary<TKey, TValue> multiValueDictionary, TKey key)
{
IReadOnlyCollection<TValue> values;
return !multiValueDictionary.TryGetValue(key, out values) ? new List<TValue>(0).AsReadOnly() : values;
}
EDIT: The new .Net 4.6 adds an API to get an empty array: Array.Empty<T> and arrays implement IReadOnlyCollection<T>. This also reduces allocations as it only creates an instance once:
IReadOnlyCollection<int> emptyReadOnlyCollection = Array.Empty<int>();
What I ended up doing is mimicking the implementation of Enumerable.Empty using new TElement[0]:
public static class ReadOnlyCollection
{
public static IReadOnlyCollection<TResult> Empty<TResult>()
{
return EmptyReadOnlyCollection<TResult>.Instance;
}
private static class EmptyReadOnlyCollection<TElement>
{
static volatile TElement[] _instance;
public static IReadOnlyCollection<TElement> Instance
{
get { return _instance ?? (_instance = new TElement[0]); }
}
}
}
Usage:
IReadOnlyCollection<int> emptyReadOnlyCollection = ReadOnlyCollection.Empty<int>();
return new List<XElement>().AsReadOnly();
I don't think there's anything like Enumerable.Empty for read-only collections, but:
List<T> already implements IReadOnlyCollection<T> so you can avoid one object allocation by not calling AsReadOnly() and simply casting the list instead. This is less "safe" in theory but hardly matters in practice.
Alternatively, you could cache the returned ReadOnlyCollection to avoid any object allocation whatsoever (except for the cached object).
As far as I know there is no built in way(Interested to know if one). That said, you can use the following:
IReadOnlyCollection<TValue> readonlyCollection = new ReadOnlyCollection<TValue>(new TValue[] { });
Optionally you can cache the results as it is a ReadOnlyCollection over empty array, It will always be the same no matter how many instances you have.
How's about this which has a similar syntax to Enumerable.Empty:
/// <summary>
/// Contains a method used to provide an empty, read-only collection.
/// </summary>
public static class ReadOnlyCollection
{
/// <summary>
/// Returns an empty, read-only collection that has the specified type argument.
/// </summary>
/// <typeparam name="T">
/// The type to assign to the type parameter of the returned generic read-only collection.
/// </typeparam>
/// <returns>
/// An empty, read-only collection whose type argument is T.
/// </returns>
public static IReadOnlyCollection<T> Empty<T>()
{
return CachedValueProvider<T>.Value;
}
/// <summary/>
static class CachedValueProvider<T>
{
/// <summary/>
public static readonly IReadOnlyCollection<T> Value = new T[0];
}
}
Used like this:
IReadOnlyCollection<int> empty = ReadOnlyCollection.Empty<int>();