How to create an empty IReadOnlyCollection - c#

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>();

Related

Class acting like a Generic Stack?

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();
}
}
}

Is there a way to find a collection in a class based on its type?

I am thinking of EF's DBContext and DBSets as the background to this question. You can access a particular set using the following code in a Repository class for example.
public TEntity Get(int id)
{
return Context.Set<TEntity>().Find(id);
}
Where Set<TEntity>() returns the set of type TEntity. How exactly is this coded? I tried to find the source code for it to no avail. Would I need to create my own classes and write the logic out in full?
TLDR: EF creates just a DbSet<T> entry in a dictionary where the the key is typeof(T).
Looking at the sourcecode it is implemented as following:
/// <summary>
/// Creates a <see cref="DbSet{TEntity}" /> that can be used to query and save instances of <typeparamref name="TEntity" />.
/// </summary>
/// <typeparam name="TEntity"> The type of entity for which a set should be returned. </typeparam>
/// <returns> A set for the given entity type. </returns>
public virtual DbSet<TEntity> Set<TEntity>()
where TEntity : class
=> (DbSet<TEntity>)((IDbSetCache)this).GetOrAddSet(DbContextDependencies.SetSource, typeof(TEntity));
And Line 195:
/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
object IDbSetCache.GetOrAddSet(IDbSetSource source, Type type)
{
CheckDisposed();
if (!_sets.TryGetValue(type, out var set))
{
set = source.Create(this, type);
_sets[type] = set;
}
return set;
}
Where sets is:
private readonly IDictionary<Type, object> _sets = new Dictionary<Type, object>();
I'm guessing Enumerable.OfType<TResult>() will come in handy here. It returns an IEnumerable<TResult> over all the elements of type TResult in the source enumeration. As for its implementation, MSDN has this to say:
This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.
I don't know how EF does it, but you could easily accomplish something similar with a Dictionary keyed by Types
private Dictionary<Type, ICollection> registry = new Dictionary<Type, ICollection>();
// adds a collection of a certain type
public void Add<T>(T collection) where T: ICollection {
registry.Add(typeof(T), collection);
}
// create an empty collection of type T and add it to registry
public void InitCollection<T>() where T: ICollection {
registry.Add(typeof(T), (ICollection)Activator.CreateInstance(typeof(T)));
}
// returns a collection of type T if it has been registered
public T Set<T>() where T: ICollection {
return (T)registry[typeof(T)];
}

Using object references as keys in a Dictionary in C# [duplicate]

Is it possible to use an object as a key for a Dictonary<object, ...> in such a way that the Dictionary treats objects as equal only if they are identical?
For example, in the code below, I want Line 2 to return 11 instead of 12:
Dictionary<object, int> dict = new Dictionary<object, int>();
object a = new Uri("http://www.google.com");
object b = new Uri("http://www.google.com");
dict[a] = 11;
dict[b] = 12;
Console.WriteLine(a == b); // Line 1. Returns False, because a and b are different objects.
Console.WriteLine(dict[a]); // Line 2. Returns 12
Console.WriteLine(dict[b]); // Line 3. Returns 12
The current Dictionary implementation uses object.Equals() and object.GetHashCode() on the keys; but I am looking for a different kind of dictionary that uses the object's identity as a key (instead of the object's value). Is there such a Dictionary in .NET or do I have to implement it from scratch?
You don't need to build your own dictionary - you need to build your own implementation of IEqualityComparer<T> which uses identity for both hashing and equality. I don't think such a thing exists in the framework, but it's easy enough to build due to RuntimeHelpers.GetHashCode.
public sealed class IdentityEqualityComparer<T> : IEqualityComparer<T>
where T : class
{
public int GetHashCode(T value)
{
return RuntimeHelpers.GetHashCode(value);
}
public bool Equals(T left, T right)
{
return left == right; // Reference identity comparison
}
}
I've restricted T to be a reference type so that you'll end up with objects in the dictionary; if you used this for value types you could get some odd results. (I don't know offhand how that would work; I suspect it wouldn't.)
With that in place, the rest is easy. For example:
Dictionary<string, int> identityDictionary =
new Dictionary<string, int>(new IdentityEqualityComparer<string>());
Of course the other answers are entirely correct, but I wrote my own version to suit my needs:
/// <summary>
/// An equality comparer that compares objects for reference equality.
/// </summary>
/// <typeparam name="T">The type of objects to compare.</typeparam>
public sealed class ReferenceEqualityComparer<T> : IEqualityComparer<T>
where T : class
{
#region Predefined
private static readonly ReferenceEqualityComparer<T> instance
= new ReferenceEqualityComparer<T>();
/// <summary>
/// Gets the default instance of the
/// <see cref="ReferenceEqualityComparer{T}"/> class.
/// </summary>
/// <value>A <see cref="ReferenceEqualityComparer<T>"/> instance.</value>
public static ReferenceEqualityComparer<T> Instance
{
get { return instance; }
}
#endregion
/// <inheritdoc />
public bool Equals(T left, T right)
{
return Object.ReferenceEquals(left, right);
}
/// <inheritdoc />
public int GetHashCode(T value)
{
return RuntimeHelpers.GetHashCode(value);
}
}
Design rationale:
The class is sealed.
If the class is not designed to be extended, I'm going to avoid all that expense by sealing it.— Eric Lippert
I know many people (including myself) who believe that classes should indeed be sealed by default.— Jon Skeet
There is an Instance static read-only property to expose a single instance of this class.
It uses Object.ReferenceEquals() instead of == because ReferenceEquals is more explicit.
It uses RuntimeHelpers.GetHashCode() because I don't want to use the possibly overridden GetHashCode of the object, which may not match the behavior of ReferenceEquals. This also avoids a null-check.
It has documentation.
Use your own equality comparer
public class ObjectIdentityEqualityComparer : IEqualityComparer<object>
{
public int GetHashCode(object o)
{
return o.GetHashCode();
}
public bool Equals(object o1, object o2)
{
return object.ReferenceEquals(o1, o2);
}
}
Note that GetHashCode can be overridden, but the crucial check is made with Equals.
As of 5.0, ReferenceEqualityComparer now ships with the runtime.
Use Dictionary with IEqualityComparer<TKey> comparer

InvalidCastException while casting to defined Type C#

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.

Extension Methods and generics - How should I be doing this?

I'm in the middle of overhauling some code and I hit a bit of a snag.
This is the method which I currently have, it needs reworking to support some structure changes:
/// <summary>
/// Recreates a dashboard control based off of its settings.
/// </summary>
/// <typeparam name="T"> The type of control to be recreated. </typeparam>
/// <param name="settings"> The known settings needed to recreate the control.</param>
/// <returns> The recreated control. </returns>
public static T Recreate<T>(ISetting<T> settings) where T : new()
{
T _control = new T();
settings.SetSettings(_control);
Logger.DebugFormat("Recreated control {0}", (_control as Control).ID);
return _control;
}
ISetting is being removed completely in favor of an extension method known to _control.
So, I have now:
public static class RadControlExtensions
{
public static RadDockZoneSetting GetSettings(this RadDockZone dockZone)
{
RadDockZoneSetting radDockZoneSetting = new RadDockZoneSetting(dockZone.UniqueName, dockZone.ID, dockZone.Skin, dockZone.MinHeight,
dockZone.HighlightedCssClass, dockZone.BorderWidth, dockZone.Parent.ID);
return radDockZoneSetting;
}
public static RadTabSetting GetSettings(this RadTab tab, int index)
{
RadTabSetting radTabSetting = new RadTabSetting(tab.Text, tab.Value, index);
return radTabSetting;
}
//Continued
}
The control that is being recreated is guaranteed to have this extension method (would be nice to enforce this, though.)
I'm now at:
public static T Recreate<T>() where T : new()
{
T _control = new T();
//Not right -- you can't cast a control to an extension method, obviously, but
//this captures the essence of what I would like to accomplish.
(_control as RadControlExtension).SetSettings();
Logger.DebugFormat("Recreated control {0}", (_control as Control).ID);
return _control;
}
What should I be looking into to support this, if possible?
If you know that every _control that gets passed will be a RadDockZone (or derived from RadDockZone) just do this:
T _control = new T();
(RadDockZone)_control.SetSettings();
Logger.DebugFormat("Recreated control ... //rest of code here
If it's not always going to be a RadDockZone, you'll need to do some type checking to get the right type to call the extension method. I'm presuming, there, that you have a .SetSettings() extension method on all the possible Types that could be passed to your Recreate method.
You need to cast your T to something that is supported by your extension method.
(_control as RadDockZone).GetSettings
Extension methods operate on a type they are not a type in the traditional sense. The 'SomeFn(string this)' makes your extension work on things that are strings which would be strings and anything derived from them.
If I understand correctly what you are trying to do, just put a constraint on T:
public static T Recreate<T>() where T : RadControl, new() {
// etc.
}
You might have to use double dispatch and define
public static RadControl GetSettings(this RadControl control) {
}
which will invoke the appropriate GetSettings method.
No, Jason's answer is the cleaner way to go. The accepted solution killed the type safety and made use of generics pointless. You could switch to generic-less design (having a RadControlFactory) and had the job done.

Categories