This question already has answers here:
How do I implement IEnumerable<T>
(6 answers)
An example for supporting foreach without implementing IEnumerable
(2 answers)
Closed 5 years ago.
Tried to make a custom HashMap class but im stuck with GetEnumerator.
When i hover over 'test.entrySet()' this shows up
'foreach statement cannot operate on variables of type 'Project.Map' does not contain a public definition for 'GetEnumerator''
My foreach loop looks like this
foreach(Map<string, object> e in test.entrySet()) {
}
My HashMap class looks like this
public class HashMap<K, V> {
private List<object> k = new List<object>();
private List<object> v = new List<object>();
public void put(object k, object v) {
this.k.Add(k);
this.v.Add(v);
}
public object get(object k) {
var i = 0;
foreach (var key in this.k) {
if (k.Equals(key)) {
return this.v.ElementAt(i);
}
i++;
}
return null;
}
public bool exist(object k) {
return this.k.Contains(k);
}
public void clear() {
this.k.Clear();
this.v.Clear();
}
public Map entrySet() {
return null;
}
}
My Map class looks like. I think this class is useless...
public class Map<K,V> {
private List<object> k = new List<object>();
private List<object> v = new List<object>();
public Map(List<object> k, List<object> v) {
this.k = k;
this.v = v;
}
public object getKey() {
return null;
}
public object getValue() {
return null;
}
}
If someone could help me fix this code/give some tips i would be verry glad.
Should look somthing like this
HashMap<string, object test = new HashMap<string, object>();
foreach(Map<string, object> e in test.entrySet()) {
string key = e.getKey();
string value = e.getValue();
}
I don't think you want your getValues() method to return a Map. If you want to get the values in the HashMap, then just return the v object.
public List<object> getValues() {
return v.AsReadOnly();
}
Also a side note, your HashMap class has generic variables but their not used anywhere. You want to replace object with whatever the generic type is.
i.e
private List<K> k = new List<K>();
private List<V> v = new List<V>();
and change your functions
i.e.
public V get(K k) {
Related
This question already has answers here:
How do i convert a class (which is derived from a generic "base" class) to that generic "base" class
(4 answers)
Why can't I assign a List<Derived> to a List<Base>?
(5 answers)
Closed 4 years ago.
I am trying to cast a generic type to a non generic one that inherits from it but it fails. Check the code below:
public class Subscription
{
public Subscription(DateTime expiration)
{
Expiration = expiration;
}
public DateTime Expiration { get; set; }
}
public class Subscription<T> : Subscription
{
public T Parameters { get; }
public Subscription(DateTime expiration, T data)
: base(expiration)
{
Parameters = data;
}
}
public class SubscriptionsService
{
private readonly ConcurrentDictionary<int, object> subscriptions;
public SubscriptionsService(ConcurrentDictionary<int, object> subscriptions)
{
this.subscriptions = subscriptions;
}
public void Add<T>(int clientId, DateTime expiration, T parameters)
{
if (!subscriptions.TryGetValue(clientId, out var outObject))
{
Subscription<T> subscription = new Subscription<T>(expiration, parameters);
List<Subscription<T>> clientSubscriptions = new List<Subscription<T>>()
{
subscription
};
subscriptions.AddOrUpdate(clientId, parameters, (k, v) => parameters);
}
else
{
if (outObject is List<Subscription<T>> resourceSubscriptions && resourceSubscriptions.Any())
{
Subscription<T> subscription = resourceSubscriptions.SingleOrDefault(x => x.Parameters.Equals(parameters));
if (subscription == null)
{
subscription = new Subscription<T>(expiration, parameters);
resourceSubscriptions.Add(subscription);
}
else
{
subscription.Expiration = expiration;
}
}
}
}
public void Cleanup()
{
// Iterate through each reportId subscription
foreach (KeyValuePair<int, object> subscriptionKeyValuePair in subscriptions)
{
List<Subscription> subscriptions = (subscriptionKeyValuePair.Value as List<Subscription>);
if (subscriptions == null || !subscriptions.Any())
continue;
foreach (var subscription in subscriptions)
{
if (subscription.Expiration > DateTime.Now)
{
//some code
}
}
}
}
}
When I call the method Cleanup and iterate through the keyvalue pairs I am trying to cast the values of the dictionary to the non-generic type that I use to add it to the Add Method. I add as List> and try to cast it as List in order to use the only the Expiration property as I dont need the T Parameters inside Cleanup. As a result List<Subscription> subscriptions casts fails and ```susbcriptions`` is always null even if value in the dictionary is not.
You are not able to make this cast because the T in List<T> is an invariant type parameter. That means C# does not treat List<A> as a derived type of List<B>, even if A derives from B.
However, IEnumerable<T> has a special feature called a "covariant type parameter". It allows you to do this type of cast. This means that in following example, the lines with list1 and list2 will result in a compiler error, but list3 would work just fine.
public class Program<T>
{
public void Main()
{
IList<Subscription> list1 = new List<Subscription<T>>();
List<Subscription> list2 = new List<Subscription<T>>();
IEnumerable<Subscription> list3 = new List<Subscription<T>>();
}
}
public class Subscription<T> : Subscription
{
}
public class Subscription
{
}
See https://learn.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance for a more detailed explanation of covariance.
In C# is it possible to convert an array type to singular - for use with Activator.CreateInstance. Take this for example:
void Main()
{
var types = new[] { typeof(ExampleClass), typeof(ExampleClass[]) };
var objects = new List<object>();
foreach (var type in types)
{
// possibly convert type here? (from array to singular - type[] to type)
Debug.WriteLine($"{type}");
objects.Add(Activator.CreateInstance(type));
}
}
// Define other methods and classes here
public class ExampleClass
{
public int X;
public int Y;
}
Gets the following output:
If I understand your Question right you might want something like this using Type.GetElementType() via reflection.
static void Main(string[] args)
{
var types = new[] { typeof(ExampleClass), typeof(ExampleClass[]) };
var objects = new List<object>();
foreach (var type in types)
{
var typeInstance = type.GetElementType();
if (typeInstance != null)
{
Debug.WriteLine($"{typeInstance}");
objects.Add(Activator.CreateInstance(typeInstance));
}
else
{
objects.Add(Activator.CreateInstance(type));
}
}
}
public class ExampleClass
{
public int X;
public int Y;
}
If I understand your question correctly, you want to get the base-type of an array, right? That should be quite easy with the IsArray property of the type, simply check each entry of your list like this:
private static Type GetTypeOrElementType(Type type)
{
if (!type.IsArray)
return type;
return type.GetElementType();
}
Btw, if you want to create a new Array of that specific type, you can use Array.CreateInstance instead of Activator.CreateInstance
Found this works:
void Main()
{
var types = new[] { typeof(ExampleClass), typeof(ExampleClass[]) };
var objects = new List<object>();
foreach (var type in types)
{
Debug.WriteLine($"{type}");
objects.Add(type.IsArray
? Activator.CreateInstance(type, 1)
: Activator.CreateInstance(type));
}
}
// Define other methods and classes here
public class ExampleClass
{
public int X;
public int Y;
}
This question already has answers here:
Delegate for an Action< ref T1, T2>
(2 answers)
Closed 7 years ago.
I have got the following method
public static void Method1(ref List<int> list)
{//code to update list}
Is it possible to create a method that takes this method as a parameter similar to (but instead of Action< List> it uses Action< ref List>)
public static void Method2(Action<List<int>> otherMethod)
{var newList = new List<int>(); otherMethod(newList)}
My main problem is that my method uses reference while Action> does not take references. Is this possible?
Yes, but you can't use Action<>/Func<> for it, you have to build the delegate "manually":
// Your method
public static void Method1(ref List<int> list)
{
}
// The delegate
public delegate void Method1Delegate(ref List<int> list);
// A method that accepts the delegate and uses it
public static void Method2(Method1Delegate del)
{
List<int> list = null;
del(ref list);
}
class App
{
private readonly Dictionary<Type, object> delegateMap;
void Add<T>(Action<SomeClass<T>> foo)
{
object tmp;
if (!delegateMap.TryGetValue(typeof(T), out tmp))
{
tmp = new List<Action<SomeClass<T>>>();
delegateMap[typeof(t)] = tmp;
}
List<Action<SomeClass<T>> list = (List<Action<SomeClass<T>>) tmp;
list.Add(foo);
}
void InvokeActions<T>(SomeClass<T> item)
{
object tmp;
if (delegateMap.TryGetValue(typeof(T), out tmp))
{
List<Action<SomeClass<T>> list = (List<Action<SomeClass<T>>) tmp;
foreach (var action in list)
{
action(item);
}
}
}
}
Use Delegates.
I have an abstract base class that holds a Dictionary. I'd like inherited classes to be able to access the dictionary fields using a convenient syntax. Currently I have lots of code like this:
string temp;
int val;
if (this.Fields.TryGetValue("Key", out temp)) {
if (int.TryParse(temp, out val)) {
// do something with val...
}
}
Obviously I can wrap this in utility functions but I'd like to have a cool, convenient syntax for accessing the dictionary fields where I can simply say something like:
int result = #Key;
Is there any way to do something like this in C# (3.5)?
You could add an indexer to your class and pass the indexer's parameter through to the dictionary.
class Foo
{
// Initialized elsewhere
Dictionary<String,String> Fields;
public Int32 this[String key]
{
String temp = null;
Int32 val = 0;
if (this.Fields.TryGetValue(key, out temp)) {
Int32.TryParse(temp, out val);
}
return val;
}
}
Then given an instance of Foo called foo you could do this:
Int32 value = foo["Key"];
How about an extension method?
public static int TryGetInt(this IDictionary dict, string key)
{
int val;
if (dict.Contains(key))
{
if (int.TryParse((string)dict[key], out val))
return val;
else
throw new Exception("Value is not a valid integer.");
}
throw new Exception("Key not found.");
}
The closer you can get to a nice syntax is using extension methods:
public static class MyDictExtensionMethods
{
public static T Get<T>(this Dictionary<string, object> dict, string key)
where T: IConvertible
{
object tmp;
if (!dict.TryGetValue(key, out tmp))
return default(T);
try {
return (T) Convert.ChangeType(tmp, typeof(T));
} catch (Exception) {
return default(T);
}
}
}
Usage:
int val = this.Fields.Get<int>("Key");
You can then create additional overloads for specific types (i.e.: types that does not implement IConvertible and need specific conversion).
Assuming that it's not always an int you want (if it is, then why isn't it a Dictionary<string, int>?) - I think something like this works and gets pretty close:
int i = #int["Key"];
string s = #string["Key"];
object o = #object["Key"];
This combines the fact that identifiers can be prefixed with # (it's usually optional, but it's required if your identifier is a reserved keyword, like int or string) with the default indexed parameter from Andrew Hare's answer.
It does require another class to be used to get the indexing - though if you wanted to use parens instead of square brackets for the key name, you could use methods instead:
int i = #value<int>("Key");
Implementation would be something like:
class DerivedClass : BaseClass {
void Main() {
int i = #int["Key"];
}
}
abstract class BaseClass {
private Dictionary<string, string> D { get; set; }
protected Indexer<int> #int = new Indexer<int>(s => int.Parse(s), this);
protected Indexer<string> #string = new Indexer<string>(s => s, this);
protected Indexer<object> #object = new Indexer<object>(s => (object)s, this);
protected class Indexer<T> {
public T this[string key] {
get { return this.Convert(this.BaseClass.D[key]); }
}
private T Convert(string value) { get; set; }
private BaseClass { get; set; }
public Indexer(Func<T, string> c, BaseClass b) {
this.Convert = c;
this.BaseClass = b;
}
}
}
Or, the method route:
class DerivedClass : BaseClass {
void Main() {
int i = #value<int>("key");
}
}
abstract class BaseClass {
private Dictionary<string, string> D { get; set; }
protected T #value<T>(string key) {
string s = this.D[s];
return Convert.ChangeType(s, typeof(T));
}
}
After reading through the language spec - if you're not tied to #, _ is a legal identifier. Combine that with indexers and you get:
int i = _["key"];
how is it possible to know whether an object implements an indexer?, I need to share a logic for a DataRow and a IDataReader, but they don't share any interface.
I tried also with generics but don't know what restriction should I put on the where clause.
public class Indexer {
// myObject should be a DataRow or a IDataReader
private object myObject;
public object MyObject {
get { return myObject; }
set { myObject = value; }
}
// won't compile, myObject has no indexer
public object this[int index] {
get { return myObject[index]; }
set { myObject[index] = value; }
}
public Indexer(object myObject) {
this.myObject = myObject;
}
}
public class Caller {
void Call() {
DataRow row = null;
IDataReader reader = null;
var ind1 = new Indexer(row);
var ind2 = new Indexer(reader);
var val1 = ind1[0];
var val2 = ind1[0];
}
}
You'd need to declare an interface with an indexer property, use that interface as the constraint, and the type argument class would need to implement that interface in order to satisfy the constraint.
As you don't control the classes you want to use, that wouldn't work.
An alternative is to make the Indexer class take the get/set operations as separate parameters:
public class Indexer {
private Func<int, object> getter;
private Action<int, object> setter;
public object this[int index]
{
get { return getter(index); }
set { setter(index, value); }
}
public Indexer(Func<int, object> g, Action<int, object> s)
{
getter = g;
setter = s;
}
}
public static class IndexerExtensions
{
public static Indexer ToIndexer(this DataRow row)
{
return new Indexer(n => row[n], (n, v) => row[n] = v);
}
public static Indexer ToIndexer(this IDataReader row)
{
return new Indexer(n => row[n], (n, v) => row[n] = v);
}
}
You could then do this:
DataRow row = null;
IDataReader reader = null;
var ind1 = row.ToIndexer();
var ind2 = reader.ToIndexer();
var val1 = ind1[0];
var val2 = ind1[0];
You could make your Indexer an abstract base class, with two subclasses, one for DataRow, and one for IDataReader.
To make it easier to use, 2 factory methods could exist, such as:
var ind1 = Indexer.CreateFromDataRow(row);
var ind2 = Indexer.CreateFromIDataReader(reader);
They could create a specific base class for that type, with it's own logic for handling the indexing.
This avoids the overhead of checking types constantly for every get/set call (at the cost of a single virtual property instead of a standard property).
get {
DataRow row = myObject as DataRow;
if (row != null)
return row[index];
IDataReader reader = myObject as IDataReader;
if (reader != null)
return reader[index];
}
and use the same logic for set{}