I have been working on a list of records for some computations using a class that inherits from a List<> and implements some additional functions. Something like:
public class ComplexValue
{
public double value;
public string name;
private int type;
// More members here
}
public class ListOfComplexValues : List<ComplexValue>
{
public void UpdateValues(double parameter)
{
for (int i = 0; i < this.Count; i++)
{
this[i].value = SomeFunction(this[i].value, parameter);
}
}
}
It turns out that the computations I need to make, take one or more of those lists and generate combinations of them to produce new, much larger ones but for which I only need to keep the (double) value.
Given the size of those new lists I had to simplify them to be just lists of double because of memory issue and speed.
So I have a new class which also implements many of the functions that were implemented for the other. The code is the same, except that in one case I use this[i] and in the other this[i].value.
public class ListOfValues : List<double>
{
public void UpdateValues(double parameter)
{
for (int i = 0; i < this.Count; i++)
{
this[i] = SomeFunction(this[i], parameter);
}
}
}
Is there a way I could easily merge those two implementations, for instance ensuring that the ComplexValue class behaves like a double?
Unfortunately, it's not very clear from your question what it is you actually want to do. That is, in what way do you want "that the ComplexValue class behaves like a double"? What would the code look like, in which the ComplexValue class is used but behaves like a double?
As you're aware I'm sure, you cannot inherit double, because it's a value type. So polymorphism is not an option here, at least not on the value type itself. But if you are willing to take a step back and reevaluate what led you to the List<T>-derived classes in the first place, perhaps there are options that would work for you.
In my experience, it's very unusual for inheriting a collection type to be the correct approach; only when the subclass is doing genuine collection-oriented things, and only collection-oriented things, would subclassing a collection type be appropriate. Otherwise, it usually makes more sense to put the non-collection-oriented operations into some other class that has a collection type (like the List<T> object).
In any case (i.e. whether you compose or inherit), you could use some kind of accessor delegates to handle the disparity between collections of List<double> and of List<ComplexValue>.
For example (for the sake of clarity, I'm keeping the inherit approach here, even though IMHO composing is likely to be better):
class ListOfValues<T> : List<T>
{
private readonly Func<List<T>, int, double> _getter;
private readonly Action<List<T>, int, double> _setter;
public ListOfTValues(
Func<List<T>, int, double> getter, Action<List<T>, int, double> setter)
{
_getter = getter;
_setter = setter;
}
public void UpdateValues(double parameter)
{
for (int i = 0; i < this.Count; i++)
{
_setter(this, i, SomeFunction(_getter(this, i), parameter));
}
}
}
Then you could create your list object like this:
ListOfValues<double> doubleList = new ListOfValues<double>(
(list, i) => list[i], (list, i, value) => list[i] = value);
ListOfValues<ComplexValue> doubleList = new ListOfValues<ComplexValue>(
(list, i) => list[i].value, (list, i, value) => list[i].value = value);
Another alternative would be to do something similar to the above — i.e. provide accessor methods to map the collection type to the actual computational code — but to provide them as virtual method overrides rather than delegates:
abstract class ListOfValues<T> : List<T>
{
protected abstract double GetItemValue(int i);
protected abstract void SetItemValue(int i, double value);
public void UpdateValues(double parameter)
{
for (int i = 0; i < this.Count; i++)
{
SetItemValue(, i, SomeFunction(GetItemValue(i), parameter));
}
}
}
class ListOfDouble : ListOfValues<double>
{
protected override double GetItemValue(int i)
{
return this[i];
}
protected override void SetItemValue(int i, double value)
{
this[i] = value;
}
}
class ListOfComplexValue : ListOfValues<ComplexValue>
{
protected override double GetItemValue(int i)
{
return this[i].value;
}
protected override void SetItemValue(int i, double value)
{
this[i].value = value;
}
}
Note that all of the above could be implemented without inheriting the List<T> type. You can put the computation logic into a class that simply contains an instance of List<T> instead. Finally, note that all of the above still works even if you follow the advice that Jon provided in his first comment to your question (advice that I think is good and worth following).
Related
Basically I want to use my own types instead of primitives like int/double, but still pass around these primitive values. Something like:
interface IInt {} // My interface to represent int. If I could fake so "int" implements this, all would work.
interface IPostNumber : IInt {} // Post number is an int. But int is not type safe enough for me.
void MyFunction(IPostNumber postNumber); // My function that should accept int/IPostNumber.
MyFunction(42); // This could also work with implicit conversion, but not allowed for interfaces:(
From ispiro's suggestion I found something that should cover everything.
So I declare my interfaces independent of underlying representation, e.g.
public interface IPostNumber{}
public interface IPostNumberFrom : IPostNumber{}
public interface IPostNumberTo : IPostNumber{}
These have full interface generality such as multiple inheritance. Then the data representation is done with generic classes with implicit conversion:
public class CInt<T>
{
public int value;
public static implicit operator int(CInt<T> d) => d.value;
public static implicit operator CInt<T>(int b) => new CInt<T>() { value = b };
}
Functions that accepts IPostNumber with int, is done as such:
private int TestPostNumberInt(CInt<IPostNumber> i) => i;
private int TestPostNumberFrom(CInt<IPostNumberFrom> i) => i;
CInt<IPostNumber> a = 4; // Works
Assert.Equal(1, TestPostNumberInt(1)); // Works
Assert.Equal(1, TestPostNumberFrom(a)); // Don't compile with IPostNumber into IPostNumberFrom
Now I can always declare CString<IPostNumber>, if some post numbers are represented with string. Or a function could accept the IPostNumber interface itself, if I make some class of it. Now one little issue is that if I want to pass CInt<IPostNumberFrom> to TestPostNumber, the method must be generic with T : IPostNumber, like this:
private int TestPostNumberInt<T>(CInt<T> i) where T : IPostNumber => i;
private int TestPostNumberIntFrom<T>(CInt<T> i) where T : IPostNumberFrom => i;
and then the generic type will not be detected while using implicit conversion (must cast). But we'll see if this is a big deal.
Also for later consideration: I will have class CJSON<T> : CString<T>. From what I see it works, though argubly CJSON could have different representations as well, like byte[] in some context. (But this is taking things far). So just need to think hard about representation vs. interfaces for my domain concepts.
I think what you might be looking for are implicit operators, but unfortunately I believe they're not supported for interfaces in the C# language specification. You can do this with subclasses if need be. Here's an example:
public class MyInt
{
int SomeValue;
public TestInt(int i)
{
SomeValue = i;
}
public static implicit operator MyInt(int i)
{
return new MyInt(i);
}
public static implicit operator int(MyInt myInt)
{
return myInt.SomeValue;
}
}
To assign using an implicit operator, you can do this:
MyInt n = 3;
int x = n;
See: implicit operator using interfaces
Is it this you're looking for?
public class IInt
{
public int TheInt;
public IInt(int theInt)
{
TheInt = theInt;
}
}
and then either use:
IInt i = new IInt(42);
MyFunction(i);
or define MyFunction for int and then use:
IInt i = new IInt(42);
MyFunction(i.TheInt);
Just one more idea:
public class IInt<T> where T : struct
{
public T TheInt;
public IInt(T theInt)
{
TheInt = theInt;
}
}
You can create an extension method but that method should be explicitly called.
I guess I've seen it somewhere before, but now I can't remember nor find it. Is there a way to make a getter property with arguments?
I mean, as I can convert "float getSize();" to "float Size":
float getSize() {
return this.size;
}
float Size {
get { return this.size; }
}
Then, could I convert, for example, "float getSize(String unit);" to "float Size(String unit)" or something like that?
float getSize(String unit) {
return this.size;
}
float Size(String unit) {
get {
if (unit == Unit.Meters)
return this.size/100;
else
return this.size;
}
}
I think there's no really problem of using function at all, but may look better this way :P
To answer the question: No, it is not possible, and as already pointed out, a getter with a parameter would look just like a method.
The thing you are thinking about might be an indexed default property, which looks like this:
class Test
{
public string this[int index]
{
get { return index.ToString(); }
}
}
This allows you to index into an instance of Test, like this:
Test t = new Test();
string value = t[1];
Interestingly, having a property with parameter is possible in VB.NET, like this:
Public ReadOnly Property oPair(param As String) As Result
Get
'some code depends on param
End Get
End Property
It's not superior to a regular function, but sometimes it is nice to have such a possibility.
I know this is an old post, but I ran into wanting to do this today in C#. Whether that's a good thing or not is probably falling on the 'not' side. However, I ran across an interesting idea posted by Mark Jones at (https://social.msdn.microsoft.com/forums/en-US/5a25bc83-990e-4657-aa9c-69bca5158d48/overloaded-c-properties-with-arguments?prof=required), but I didn't quite like the feel of it.
So I wrote my own based on his (mine is in .Net 5.0 with Nullable = enable):
class ParameterizedProperty<T>
{
private readonly Func<int, T> getter;
private readonly Action<int, T> setter;
public T this[int index]
{
get => this.getter(index);
set => this.setter(index, value);
}
public ParameterizedProperty(Func<int, T> getter, Action<int, T> setter)
{
this.getter = getter;
this.setter = setter;
}
}
class NamedParameterizedProperty<T>
{
private readonly Func<int, T> indexedGetter;
private readonly Action<int, T> indexedSetter;
private readonly Func<string, T> namedGetter;
private readonly Action<string, T> namedSetter;
public T this[int index]
{
get => this.indexedGetter(index);
set => this.indexedSetter(index, value);
}
public T this[string name]
{
get => this.namedGetter(name);
set => this.namedSetter(name, value);
}
public NamedParameterizedProperty(Func<int, T> indexedGetter, Action<int, T> indexedSetter, Func<string, T> namedGetter, Action<string, T> namedSetter)
{
this.indexedGetter = indexedGetter;
this.indexedSetter = indexedSetter;
this.namedGetter = namedGetter;
this.namedSetter = namedSetter;
}
}
class ReadOnlyParameterizedProperty<T>
{
private readonly Func<int, T> getter;
public T this[int index] => this.getter(index);
public ReadOnlyParameterizedProperty(Func<int, T> getter)
{
this.getter = getter;
}
}
class ReadOnlyNamedParameterizedProperty<T>
{
private readonly Func<int, T> indexedGetter;
private readonly Func<string, T> namedGetter;
public T this[int index] => this.indexedGetter(index);
public T this[string name] => this.namedGetter(name);
public ReadOnlyNamedParameterizedProperty(Func<int, T> indexedGetter, Func<string, T> namedGetter)
{
this.indexedGetter = indexedGetter;
this.namedGetter = namedGetter;
}
}
So a little about my solution: I opted for Func<> & Action<> for the getters/setters because I didn't want this helper class to have to need any knowledge of underlying property it would be supporting. Instead, the class that owns the property would have public (or private) methods for get_X / set_X (or whatever naming convention you wish to use) that would handle everything - such as validation.
Now as to my use case for this: I had a class that has an internal array of a specific type. I have a default indexer property public primaryType this[int index], but it has a couple of other types that it understands and can convert to / from for primaryType. However, I can't do public otherType this[int index], and I didn't really want to do public methods called something like 'get_OtherType` & 'set_OtherType'.
These helper classes let me do something like:
public ParameterizedProperty<OtherType> OtherType { get; }
public MyClass()
{
this.OtherType = new(get_OtherType, set_OtherType);
}
private OtherType get_OtherType(int index)
{
/* validate index, convert PrimaryType at index to OtherType and return. */
}
private void set_OtherType(int index, OtherType value)
{
/* validate index, validate value, convert to PrimaryType and set to internal array. */
}
Then in other classes / UIs that use this class, where 'OtherType' is more convenient for them to work with then 'PrimaryType', I can have them doing things like myClass1.OtherType[0] = otherType;, but if they work with the primary type, then they can do myClass1[0] = primaryType - or if I just want to be consistent / explicit, I don't have a default indexer property, and I use a ParameterizedProperty for the primary type as well, IE: myClass1.PrimaryType[0] = primaryType;
Again, whether this is a good idea to go this route or not, I'm unsure.
It is possible for a class object to reasonably-efficiently have something that behaves as a named indexed property getter by having a property return a struct which simply holds a private reference to the class object and includes an indexed property getter which chains to a method in the class. Such a single-item structure can be generated at basically no cost (it can likely fit in a register, and will be loaded with a value that's in another register; the JIT may even be able to recognize that the same register can be used for both purposes), so if using such a getter makes code more readable that's a substantial argument in favor.
Unfortunately, the inability of struct members to indicate whether or not they modify the underlying structure makes it impossible to use the same approach for an indexed property setter. Even though it would be helpful it one could have have an OrderedCollection<T> with something like:
struct ByIndexAccessor {
OrderedCollection<T> owner;
ByIndexAccessor(OrderedCollection<T> o) { owner = o; }
T this[int index] {
get { return owner.handleGet(index); }
set { owner.handleSet(index, value); }
}
}
ByIndexAccessor ByIndex {
get {return new ByIndexAccessor(this); }
}
and say myCollection.ByIndex[3] = newThing;, C# would reject such code because it has no way of knowing that this particular indexed set implementation can safely be used on a read-only structure.
During the development of one of my projects, I encountered an issue regarding generic types.
The project requires me to write a class that would act as a source of list objects. Suppose I had the following class:
public class TablesProvider
{
private readonly List[] _tables;
public TablesProvider()
{
// initialize the tables var here....
}
public List<TItem> GetTable<TItem>()
{
return (List<TItem>)_tables.Single(x => x is List<TItem>);
}
}
This class obviously doesn't work, because the List type is a generic type and therefore the generic arguments should be specified.
So I made an abstract type called MyList, that would be derived by a more specific type MyList<TItem> in order to escape this requirement, and edited the TablesProvider a little.
public class TablesProvider
{
private readonly MyList[] _tables;
public TablesProvider()
{
// initialize the tables var here....
}
public MyList<TItem> GetTable<TItem>()
{
return (MyList<TItem>)_tables.Single(x => x is MyList<TItem>);
}
}
public abstract class MyList
{
// ...
}
public class MyList<TItem> : MyList, IList<TItem>
{
private readonly List<TItem> _elements = new List<TItem>();
public TItem this[int index]
{
get { return _elements[index]; }
set { _elements[index] = value; }
}
// ...
}
This works quite well. There is only one problem left. Suppose I had 45 different collections, each defined with a different generic argument. What would be the best way of initializing all of those collections? I cannot use a for loop here, since generic parameters are specified at compile-time and not at runtime, and therefore a construction like this wouldn't be possible:
for (int i = 0; i < 45; i++)
_tables[i] = new MyList<GenericParameters[i]>();
My ultimate goal is to have the luxury to just do something like this...
var table = _tablesProvider.GetTable<SomeClass>();
var element = table[3];
var propertyValue = element.SomeProperty;
... without the need to cast the variable element in order to access its type-specific members.
It is probably worth mentioning that the amount of different list objects is fixed to 45. This will not change. In theory, I could initialize the array line by line, or have 45 properties or variables instead. Both of these options, however, sound as a rather cheap solution to me, but I will accept one of them if there is no other way.
Any of you got some ideas? Am I doing this completely wrong? Should I consider an other structure?
Thanks in advance.
Yes, it is possible to do what you are describing if you use reflection.
Supposing that your hypothetical GenericParameters array is an array of Types (since you can't have an array of type identifiers), you can define this helper function:
private MyList MakeList(Type t)
{
return (MyList)Activator.CreateInstance(typeof(MyList<>).MakeGenericType(t));
}
And that will allow you to do this:
public TablesProvider()
{
var GenericParameters = new[] { typeof(string), typeof(int), typeof(DateTime) };
_tables = new MyList[GenericParameters.Length];
for (int i = 0; i < GenericParameters.Length; i++)
{
_tables[i] = MakeList(GenericParameters[i]);
}
}
You can even use LINQ if you want:
public TablesProvider()
{
var GenericParameters = new[] { typeof(string), typeof(int), typeof(DateTime) };
_tables = GenericParameters.Select(MakeList).ToArray();
}
Previous answer:
Well, the reality is that you're going to have a list of 45 different types somewhere, which pretty much means you're going to have 45 different lines of similar code. So one could say the goal is to make those lines as concise as possible.
One way to do so would be to add a helper function:
private void AddTable<T>()
{
_tables.Add(new MyTable<T>());
}
(this assumes changing _tables to a List<MyTable>)
Then you could just do:
AddTable<Type1>();
AddTable<Type2>();
AddTable<Type3>();
AddTable<Type4>();
this implementation works
public class TablesProvider
{
private readonly List<object> _tables;
public TablesProvider()
{
_tables = new List<object>();
}
public IList<TItem> GetTable<TItem>()
{
var lst = (List<TItem>)_tables.SingleOrDefault(x => x is List<TItem>);
if (lst == null)
{
lst = new List<TItem>();
_tables.Add(lst);
}
return lst;
}
}
it creates List of TItem when necessary; next time it returns the same list for TItem. it is lazy initialization
so you can do invoke
var table = _tablesProvider.GetTable<SomeClass>();
without any code like this:
for (int i = 0; i < 45; i++)
_tables[i] = new MyList<GenericParameters[i]>();
it is not ThreadSafe
I have a class which is defined in the following manner. The interface and concrete type both have a Type Parameter which I expect to be a double, int, decimal or DateTime. I've added a where constraint of IComparable however this class does some heavy numeric lifting so I want to avoid boxing and unboxing. The class definitions are as follows:
public interface INumericClass<T1, T2> where T1:IComparable
where T2:IComparable
{
void DoLongNumericOperation();
}
public class NumericClass<T1, T2> : INumericClass<T1, T2> where T1:IComparable
where T2:IComparable
{
private IList _innerArray1 = new T1[1000000];
private IList _innerArray2 = new T2[1000000];
public void DoLongNumericOperation()
{
for(int i = 0; i < _innerArray1.Count; i++)
{
// some computation goes on in here
// for example, it could be
double aConstant = 123.45;
double aScalar = 56.7;
_innerArray1[i] = (Convert.ToDouble(_innerArray1[i]) * aConstant + aScalar);
_innerArray2[i] = (Convert.ToDouble(_innerArray2[i]) * aConstant + aScalar);
}
}
}
These classes would be declared and used in calling code something like as follows
var numeric = new NumericClass<int, double>();
numeric.DoLongNumericComputation();
Now internally the way I handle the multiple types is to cast T to double. However I am concerned that since I have specified that T is a type param of type IComparable that unboxing/boxing is going on. In addition DateTime provides an additional overhead. What I am doing in the case of this type is converting the .Ticks property to a double and operating on that.
I welcome any information on what is going on under the hood in the CLR, plus suggestions to improve performance such as API changes to strongly type each of the numeric operations to improve performance and memory usage.
Edit: I should also add the above implementation is sub-optimum as if you declare NumericClass it starts throwing on the cast from Tx to double. I can only assume its casting through IComparable although Im not sure.
Without seeing a more complete example, here is what I can recommend.
public interface IConvertToDouble<T>
where T : IComparable
{
double Convert(T input);
T ConvertBack(double input);
}
public class NumericClass<T, U>
where T : IComparable,
U : IComparable
{
private IConvertToDouble<T> _tConverter;
private IConvertToDouble<U> _uConverter;
private List<T> _internalTs;
private List<U> _internalUs;
public NumericClass(IConvertToDouble<T> tConverter, IConvertToDouble<U> uConverter)
{
_tConverter = tConverter;
_uConverter = uConverter;
_internalTs = new List<T>();
_internalUs = new List<U>();
}
public void DoLongNumericOperation()
{
for(int i = 0; i < innerArray.Length; i++)
{
// some computation goes on in here
// for example, it could be
double aConstant = 123.45;
double aScalar = 56.7
_internalTs[i] = _tConverter.ConvertBack(_tConverter.Convert(_internalTs[anIndex]) * aConstant + aScalar);
_internalUs[i] = _uConverter.ConvertBack(_uConverter.Convert(_internalUs[anIndex]) * aConstant + aScalar);
}
}
}
Now you don't need to cast your generic objects or have type specific logic in NumericClass.
See Generic operators.
When is it acceptable for an indexer to automatically add items to a collection/dictionary? Is this reasonable, or contrary to best practices?
public class I { /* snip */ }
public class D : Dictionary<string, I>
{
public I this[string name]
{
get
{
I item;
if (!this.TryGetValue(name, out item))
{
item = new I();
this.Add(name, item);
}
return item;
}
}
}
Sample of how this may be used in a collection:
public class I
{
public I(string name) {/* snip */}
public string Name { get; private set; }
/* snip */
}
public class C : Collection<I>
{
private Dictionary<string, I> nameIndex = new Dictionary<string, I>();
public I this[string name]
{
get
{
I item;
if (!nameIndex.TryGetValue(name, out item))
{
item = new I(name);
this.Add(item); // Will also add the item to nameIndex
}
return item;
}
}
//// Snip: code that manages nameIndex
// protected override void ClearItems()
// protected override void InsertItem(int index, I item)
// protected override void RemoveItem(int index)
// protected override void SetItem(int index, I item)
}
There's two problems that you should consider - both of which suggest this is a bad idea.
First, inheriting from the .NET BCL collection types is not generally a good idea. The main reason for this is that most methods on those types (like Add and Remove) are not virtual - and if you provide your own implementations in a derived class, they will not get called if you pass your collection around as the base type. In your case, by hiding the Dictionary<TK,TV> indexer property, you are creating a situation where a call using a base-class reference will do something different than a call using a derived-class reference ... a violation of the Liskov Substitution Principle:
var derived = new D();
var firstItem = derived["puppy"]; // adds the puppy entry
var base = (Dictionary<string,I>)derived;
var secondItem = base["kitten"]; // kitten WAS NOT added .. BAD!
Second, and more importantly, creating an indexer that inserts an item when you attempt to find one is entirely unexpected. Indexers have clearly defined get and set operations - implementing the get operation to modify the collection is very bad.
For the case you describe, you're much better off creating an extension method that can operate on any dictionary. Such an operation is both less surprising in what it does, and also doesn't require creating a derived collection type:
public static class DictionaryExtensions
{
public static TValue FindOrAdd<TKey,TValue>(
this IDictionary<TKey,TValue> dictionary, TKey key, TValue value )
where TValue : new()
{
TValue value;
if (!this.TryGetValue(key, out value))
{
value = new TValue();
this.Add(key, value);
}
return value;
}
}
With no other information about what you're doing, that looks like surprising behavior to me. I hope that you make it very clear from the context (i.e. name it an AutoInitializingDictionary or something) what's to be expected.
I would personally prefer to make this a method rather than an indexer; something like D.FindOrCreate. (I have the feeling there's an idiomatic name for a method that does this which I've temporarily forgotten.)
I would say this violates two principles. 1) principle of least surprise. And 2) that getters shouldn't change anything.
I wouldn't expect to add a the pair {"foo", null} if foo doesn't exist in the colleciton.
x = collection["Foo"]
I think it is perfectly fine as long as this behaviour is made perfectly clear. I have 2 decorator classes:
public class DefaultValueDictionary<K, V> : IDictionary<K, V>
{
public DefaultValueDictionary(IDictionary<K, V> baseDictionary, Func<K, V> defaultValueFunc)
{
...
}
}
and
public class ParameterlessCtorDefaultValueDictionary<K, V>
: DefaultValueDictionary<K, V> where V : new()
{
public ParameterlessCtorDefaultValueDictionary(IDictionary<K, V> baseDictionary)
: base(baseDictionary, k => new V())
{
...
}
}
The second class is perfect for counters and patterns like IDictionary<K,List<V>>;
I can do
var dict = new ParameterlessCtorDefaultValueDictionary<string, int>();
...
dict[key]++;
instead of the laborious:
int count;
if(!dict.TryGetValue(key, out count))
dict[count] = 1;
else dict[count] = count + 1;
The primary reason I would be concerned is that it wouldn't be thread-safe. Multiple readers all attempting to possibly write to the Dictionary at once would require careful lock management that you wouldn't likely think of (or get right) at first.
When is it acceptable for an indexer
to automatically add items to a
collection/dictionary?
Never
Is this reasonable, or contrary to
best practices?
Contrary to best practices
That said, if the class is named appropriately, it'd be acceptable. I'd personally use GetOrAdd instead.