I'm pretty darn new to C# and I can't figure out how to express something pretty simple.
I have a 3D array that is private.
I have no problem with the function that exposes the contents to read:
public Terrain Tile(int x, int y, int z) { return ....
but I also want an internal function that provides read/write access with a coordinate transformation.
There seems to be no way to specify a setter.
Looking at Microsoft's site it appears that it wants []'s instead of ()'s but that results in the compiler thinking it's an array definition and of course it barfs all over the place. Googling elsewhere I find plenty of people trying to modify a field of something returning a reference type which of course fails but this array is full of enums, not reference types.
Of course I can write a SetTile(x, y, z, terrain) function but being able to access it as an array is so much more clear & elegant, yet it appears to be impossible.
You can define a 'view' class with an indexer which is basically a property with arguments:
private Terrain[,,] rawArray = ...;
private View transformedArray = new View(rawArray);
private class View
{
private Terrain[,,] array;
public View(Terrain[,,] array)
{
this.array = array;
}
public Terrain this[int x, int y, int z]
{
get { ... }
set
{
this.array[2*x, 3*z, -y] = value;
}
}
}
Here's one option:
private Terrain[,,] rawArray = ...;
private View view = new View(rawArray);
private class View
{
private class TransformedView
{
private Terrain[,,] array;
public TransformedView(Terrain[,,] array)
{
this.array = array;
}
public Terrain this[int x, int y, int z]
{
get { ... }
set
{
this.array[2*x, 3*z, -y] = value;
}
}
}
private Terrain[,,] array;
public readonly TransformedView Transformed;
public View(Terrain[,,] array)
{
this.array = array;
Transformed = new TransformedView(array);
}
public Terrain this[int x, int y, int z]
{
get { ... }
set
{
this.array[x, z, y] = value;
}
}
}
To extend on dtb's answer, I wrote the following transform class:
public class Transform<T, K>
{
Func<K, T> _getFunc1;
Func<K, K, T> _getFunc2;
Func<K, K, K, T> _getFunc3;
Action<K, T> _setFunc1;
Action<K, K, T> _setFunc2;
Action<K, K, K, T> _setFunc3;
public T this[K k1]
{
get
{
if (_getFunc1 == null) throw new ArgumentException();
return _getFunc1(k1);
}
set
{
if (_getFunc1 == null) throw new ArgumentException();
_setFunc1(k1, value);
}
}
public T this[K k1, K k2]
{
get
{
if (_getFunc2 == null) throw new ArgumentException();
return _getFunc2(k1, k2);
}
set
{
if (_getFunc2 == null) throw new ArgumentException();
_setFunc2(k1, k2, value);
}
}
public T this[K k1, K k2, K k3]
{
get
{
if (_getFunc3 == null) throw new ArgumentException();
return _getFunc3(k1, k2, k3);
}
set
{
if (_getFunc3 == null) throw new ArgumentException();
_setFunc3(k1, k2, k3, value);
}
}
public Transform(Func<K, T> getFunc) { this._getFunc1 = getFunc; }
public Transform(Func<K, T> getFunc, Action<K, T> setFunc)
: this(getFunc)
{
this._setFunc1 = setFunc;
}
public Transform(Func<K, K, T> getFunc) { this._getFunc2 = getFunc; }
public Transform(Func<K, K, T> getFunc, Action<K, K, T> setFunc)
: this(getFunc)
{
this._setFunc2 = setFunc;
}
public Transform(Func<K, K, K, T> getFunc) { this._getFunc3 = getFunc; }
public Transform(Func<K, K, K, T> getFunc, Action<K, K, K, T> setFunc)
: this(getFunc)
{
this._setFunc3 = setFunc;
}
}
Allowing you to create sample classes like the following:
class TransformUser
{
int[, ,] _array = new int[4, 4, 4];
public Transform<int, int> Normal;
public Transform<int, int> Transformed;
public TransformUser()
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
for (int k = 0; k < 4; k++)
_array[i, j, k] = i * j * k;
Normal = new Transform<int, int>((x, y, z) => _array[x, y, z]);
Transformed = new Transform<int, int>((x, y, z) => _array[x, y / 2, z]);
}
}
With a use like the following:
TransformUser tu = new TransformUser();
Console.WriteLine(tu.Normal[2, 3, 2]);
Console.WriteLine(tu. Transformed[2, 3, 2]);
Related
I making a application with compression mechanism and need my own Dictionary. Every cicle in my app, It adds new element into a myDictionary and update(add a char to some previous elements in myDictionary ). I was doing it with normal list and Quicksort function, but it was really slow. I'm searching for some new methods how to do this but SortedList, Dictionary or LookUp doesnt seems like what I looking for. Is it better to make my own SortedList or is too hard/complex to manage?
Some of the code:
public class MyDictionary
{
private List<string> Contexts;
private List<string> Contents;
private int Count; //words count
//Konstruktor
public MyDictionary()
{
Count = 0;
Contexts = new List<string>();
Contents = new List<string>();
}
region Public Functions
public void AddChar(char ch, int contentSize)
{
for (int i = 0; i < Count; i++)
{
if (Contents[i].Length < contentSize)
{
Contents[i] = Contents[i] + ch;
}
}
}
public void Add(string context, string content)
{
Contexts.Add(Reverse(context)); //otočený kontext
Contents.Add(content);
Count++;
}
public void update()
{
quicksort(Contexts, Contents, 0, Count-1);
}
private void quicksort(List<String> context, List<String> content, int left, int right)
{
int i = left, j = right;
string pivot = context[(left + right) / 2];
while (i <= j)
{
while (context[i].CompareTo(pivot) < 0)
{
i++;
}
while (context[j].CompareTo(pivot) > 0)
{
j--;
}
if (i <= j)
{
swap(i,j);
i++;
j--;
}
}
// Recursive calls
if (left < j)
{
quicksort(context, content, left, j);
}
if (i < right)
{
quicksort(context, content, i, right);
}
}
private static string Reverse(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
Here is a class that acts like a SortedDictionary, but can hold multiple values with the same key. You may need to flesh it out a little bit, with methods like Remove, and adding support for your own IComparer<TKey> if you need them. LINQPad file
public class SortedMultiValue<TKey, TValue> : IEnumerable<TValue>
{
private SortedDictionary<TKey, List<TValue>> _data;
public SortedMultiValue()
{
_data = new SortedDictionary<TKey, System.Collections.Generic.List<TValue>>();
}
public void Clear()
{
_data.Clear();
}
public void Add(TKey key, TValue value)
{
if (!_data.TryGetValue(key, out List<TValue> items))
{
items = new List<TValue>();
_data.Add(key, items);
}
items.Add(value);
}
public IEnumerable<TValue> Get(TKey key)
{
if (_data.TryGetValue(key, out List<TValue> items))
{
return items;
}
throw new KeyNotFoundException();
}
public IEnumerator<TValue> GetEnumerator()
{
return CreateEnumerable().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return CreateEnumerable().GetEnumerator();
}
IEnumerable<TValue> CreateEnumerable()
{
foreach (IEnumerable<TValue> values in _data.Values)
{
foreach (TValue value in values)
{
yield return value;
}
}
}
}
You can use it like this:
var data = new SortedMultiValue<string, string>();
data.Add("Dog", "Buddy");
data.Add("Dog", "Mr. Peanutbutter");
data.Add("cat", "Charlie");
data.Add("cat", "Sam");
data.Add("cat", "Leo");
foreach (string item in data)
{
Console.WriteLine(item);
}
Console.WriteLine();
foreach (string item in data.Get("cat"))
{
Console.WriteLine(item);
}
Console.WriteLine();
foreach (string item in data.Get("Dog"))
{
Console.WriteLine(item);
}
It produces this as the output (notice that the first group of names is sorted by the key they were inserted with):
Charlie
Sam
Leo
Buddy
Mr. Peanutbutter
Charlie
Sam
Leo
Buddy
Mr. Peanutbutter
Is there a saner way to do the following:
public static class ValueTupleAdditions {
public static IEnumerable<object> ToEnumerable<A, B>(this ValueTuple<A, B> tuple) {
yield return tuple.Item1;
yield return tuple.Item2;
}
public static IEnumerable<object> ToEnumerable<A, B, C>(this ValueTuple<A, B, C> tuple) {
yield return tuple.Item1;
yield return tuple.Item2;
yield return tuple.Item3;
}
[etc]
}
EDIT: Since people are asking for a use case, here you go.
using Xunit;
namespace Whatever {
public class SomeTestClass {
public static IEnumerable<(string, Expression<Func<string, string>>, string)> RawTestData() {
yield return ("Hello", str => str.Substring(3), "lo");
yield return ("World", str => str.Substring(0, 4), "worl");
}
public static IEnumerable<object[]> StringTestData() {
return RawTestData().Select(vt => new object[] { vt.Item1, vt.Item2, vt.Item3 });
// would prefer to call RawTestData().Select(vt => vt.ToArray()) here, but it doesn't exist.
}
[Theory, MemberData(nameof(StringTestData))]
public void RunStringTest(string input, Expression<Func<string, string>> func, string expectedOutput) {
var output = func.Compile()(input);
Assert.Equal(expectedOutput, output);
}
}
}
One way to do this is via the ITuple interface.
public interface ITuple
{
int Length { get; }
object this[int index] { get; }
}
It is only available in .NET Core 2.0, Mono 5.0 and the next version of .NET Framework (unreleased, following 4.7).
It is not (and will never be) available as an add-on to older frameworks via the ValueTuple package.
This API is designed for usage by the C# compiler for future work on patterns.
A bit of reflection:
namespace ConsoleApp1
{
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var tuple = (1, 2, 3, 4, 5, 6, 7);
var items = ToEnumerable(tuple);
foreach (var item in items)
{
Console.WriteLine(item);
}
}
private static IEnumerable<object> ToEnumerable(object tuple)
{
if (tuple.GetType().GetInterface("ITupleInternal") != null)
{
foreach (var prop in tuple.GetType()
.GetFields()
.Where(x => x.Name.StartsWith("Item")))
{
yield return prop.GetValue(tuple);
}
}
else
{
throw new ArgumentException("Not a tuple!");
}
}
}
}
One way is to use an extension method based on ITuple, see also answer by Julien Couvreur:
public static IEnumerable<T> ToEnumerable<T>( this ITuple tuple ) {
for ( var n = 0; n < tuple.Length; n++ ) yield return (T)tuple[ n ];
}
sample usage:
var directions = (
right: (cx: 1, cy: 0),
down: (cx: 0, cy: 1),
left: (cx: -1, cy: 0),
up: (cx: 0, cy: -1)
);
foreach ( var direction in directions.ToEnumerable<(int cx, int cy)>() ) {
var (cx, cy) = direction;
TryMovePiece( (x + cx, y + cy) );
}
Is there anyway to accomplish the following? Here is some simplified semi pseudo code of what I am trying to do:
class Foo {
static public FUNCTION one(int foo, int bar) {
return List<Vector> FUNCTION(int num) {
List<Vector> v = new List<Vector>();
for (int i = 0; i < num; i++) {
v.Add( new Vector(1+foo, 1+bar) );
}
return v;
}
static public FUNCTION two(int foo, int bar) {
return List<Vector> FUNCTION(int num) {
List<Vector> v = new List<Vector>();
// Do something else?
return v;
}
}
}
Then I would like to call it like so:
generic = Foo.one(1, 2);
List<Vector> v = generic(2);
generic = Foo.two(1, 2);
List<Vector> v = generic(2);
I think this is kind of along the lines of what I want but I'm unsure how to pass the first set of arguments in.
public static Func<int, int, List<Vector>> one()
{
Func<int, List<Vector>> func = (int num) =>
{
List<Vector> v = new List<Vector>();
return v;
};
return func;
}
Is that a solution for your problem? It is a construct called Closure. It is just a combination of what you already had.
public static Func<int, List<Vector>> one(int foo, int bar)
{
Func<int, List<Vector>> func =
num =>
{
List<Vector> v = new List<Vector>();
for (int i = 0; i < num; i++)
{
v.Add(new Vector(1 + foo, 1 + bar));
}
return v;
};
return func;
}
Mostly it comes handy that C# delegates already store the object together with the member function. But is there a way, to store -- and pass as parameters -- only the member function itself, just as the good old pointer-to-member-function in C++?
In case the description is less than clear, I give a self-contained example. And, yes, in the example the insistence to pass around member functions is totally pointless, but I have more serious uses for this.
class Foo {
public int i { get; set; }
/* Can this be done?
public static int Apply (Foo obj, ???? method, int j) {
return obj.method (j);
}
*/
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
return (int) method.Method.Invoke (obj, new object [] { j });
}
public static readonly Foo _ = new Foo (); // dummy object for ApplyHack
public int Multiply (int j) {
return i * j;
}
public int Add (int j) {
return i + j;
}
}
class Program {
static void Main (string [] args) {
var foo = new Foo { i = 7 };
Console.Write ("{0}\n", Foo.ApplyHack (foo, Foo._.Multiply, 5));
Console.Write ("{0}\n", Foo.ApplyHack (foo, Foo._.Add, 5));
Console.ReadKey ();
}
}
You see, the only workaround I've found is rather ugly and probably slow.
What you want is something called an open instance delegate. I've written about them on my blog
Basically, you can create a delegate to an instance method without tying it to a particular instance, and specify the instance to use it on when you call it:
class Foo {
public int i { get; set; }
public int Multiply (int j) {
return i * j;
}
public int Add (int j) {
return i + j;
}
}
class Program {
static void Main (string [] args) {
Func<Foo, int, int> multiply = (Func<Foo, int, int>)Delegate.CreateDelegate(typeof(Func<Foo, int, int>), null, typeof(Foo).GetMethod("Multiply");
Func<Foo, int, int> add = (Func<Foo, int, int>)Delegate.CreateDelegate(typeof(Func<Foo, int, int>), null, typeof(Foo).GetMethod("Add");
var foo1 = new Foo { i = 7 };
var foo2 = new Foo { i = 8 };
Console.Write ("{0}\n", multiply(foo1, 5));
Console.Write ("{0}\n", add(foo1, 5));
Console.Write ("{0}\n", multiply(foo2, 5));
Console.Write ("{0}\n", add(foo2, 5));
Console.ReadKey ();
}
}
Taking your existing code:
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
return (int) method.Method.Invoke (obj, new object [] { j });
}
You could do something like this:
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
var func = (Func<int,int>)Delegate.CreateDelegate(typeof(Func<int,int>), obj, method.Method);
return func(j);
}
This will create a new delegate around the method and the new object. To take your first example:
public static int Apply (Foo obj, ???? method, int j) {
return obj.method (j);
}
The type you are looking for is System.Reflection.MethodInfo and it would look like this:
public static int Apply (Foo obj, MethodInfo method, int j) {
var func = (Func<int,int>)Delegate.CreateDelegate(typeof(Func<int,int>), obj, method);
return func(i);
}
Note that while you are allocating delegates for each invocation, I believe this will still be faster than using reflection, since you do not have to box function input/output, nor store it in object[] arrays.
Assuming you're using C# 2.0 or above, and have access to anonymous delegates, you can do it very simply by wrapping the function in an anonymous delegate at the point of storage:
class Foo
{
public Foo(int v)
{
this.v = v;
}
int v;
public int Multiply(int x)
{
return v * x;
}
public int Add(int x)
{
return v+x;
}
delegate int NewFunctionPointer(Foo, int);
delegate int OldDelegateStyle(int);
static void Example()
{
Foo f = new Foo(2);
Foo f2 = new Foo(3);
// instead of this, which binds an instance
OldDelegateStyle oldMul = f.Multiply;
// You have to use this
NewFunctionPointer mul = delegate(Foo f, int x) { return f.Multiply(x); }
NewFunctionPointer add = delegate(Foo f, int x) { return f.Add(x); }
// But can now do this
mul(f, 4); // = 8
add(f2, 1); // = 3
}
}
If you're okay with passing the this reference as a parameter, why not just use static methods?
class Foo {
public int i;
public static int ApplyHack(Foo foo, Func<Foo, int, int> method, int j) {
return method(foo, j);
}
public static int Multiply(Foo foo, int j) {
return foo.i * j;
}
}
Console.Write("{0}\n", Foo.ApplyHack(foo, Foo.Multiply, 5));
This mainly affects how you construct the Foo object, without changing how you use it. It also doesn't prevent you from having a non-static int Multiply(int) method.
You could retrieve and reuse the MethodInfo for the method or just use the name and extract the method at runtime.
public static int ApplyHack (Foo obj, string methodName, int j)
{
var method = typeof(Foo).GetMethod(methodName);
return (int) method.Invoke (obj, new object [] { j });
}
I'd be very careful that this was actually necessary as it seems like a code smell to me.
You can do it that way
class Foo
{
public int i { get; set; }
public static int Apply(Foo obj, Func<int, int, int> method, int j)
{
return method(j, obj.i);
}
public static int Multiply(int j, int i)
{
return i * j;
}
public static int Add(int j, int i)
{
return i + j;
}
}
static void Main(string[] args)
{
var foo = new Foo { i = 7 };
Console.Write("{0}\n", Foo.Apply(foo, Foo.Multiply, 5));
Console.Write("{0}\n", Foo.Apply(foo, Foo.Add, 5));
Console.ReadKey();
}
I think you can do this easily with this if I understand correctly:
public static int Apply(Func<int, int> method, int j)
{
return (int)method.Method.Invoke(method.Target, new object[] { j });
}
and call it like this:
Console.Write("{0}\n", Foo.Apply(foo.Multiply, 5));
I have a class that internally is just an array of integers. Once constructed the array never changes. I'd like to pre-compute a good hashcode so that this class can be very efficiently used as a key in a Dictionary. The length of the array is less than about 30 items, and the integers are between -1000 and 1000 in general.
Not very clever, but sufficient for most practical purposes:
EDIT: changed due to comment of Henk Holterman, thanks for that.
int hc = array.Length;
foreach (int val in array)
{
hc = unchecked(hc * 314159 + val);
}
If you need something more sophisticated, look here.
For an array of values generally between -1000 and 1000, I would probably use something like this:
static int GetHashCode(int[] values)
{
int result = 0;
int shift = 0;
for (int i = 0; i < values.Length; i++)
{
shift = (shift + 11) % 21;
result ^= (values[i]+1024) << shift;
}
return result;
}
You may use CRC32 checksum. Here is the code:
[CLSCompliant(false)]
public class Crc32 {
uint[] table = new uint[256];
uint[] Table { get { return table; } }
public Crc32() {
MakeCrcTable();
}
void MakeCrcTable() {
for (uint n = 0; n < 256; n++) {
uint value = n;
for (int i = 0; i < 8; i++) {
if ((value & 1) != 0)
value = 0xedb88320 ^ (value >> 1);
else
value = value >> 1;
}
Table[n] = value;
}
}
public uint UpdateCrc(uint crc, byte[] buffer, int length) {
uint result = crc;
for (int n = 0; n < length; n++) {
result = Table[(result ^ buffer[n]) & 0xff] ^ (result >> 8);
}
return result;
}
public uint Calculate(Stream stream) {
long pos = stream.Position;
const int size = 0x32000;
byte[] buf = new byte[size];
int bytes = 0;
uint result = 0xffffffff;
do {
bytes = stream.Read(buf, 0, size);
result = UpdateCrc(result, buf, bytes);
}
while (bytes == size);
stream.Position = pos;
return ~result;
}
}
I think choosing a good hash-algorithm would have to be based on the distribution (in a probability sense) of the integer values.
Have a look at Wikipedia for a list of algorithms
Any CRC (or even XOR) should be ok.
You could take a different approach and use a recursive dictionary for each value in your int array. This way you can leave .net to do primitive type hashing.
internal class DictionaryEntry<TKey, TValue>
{
public Dictionary<TKey, DictionaryEntry<TKey, TValue>> Children { get; private set; }
public TValue Value { get; private set; }
public bool HasValue { get; private set; }
public void SetValue(TValue value)
{
Value = value;
HasValue = true;
}
public DictionaryEntry()
{
Children = new Dictionary<TKey, DictionaryEntry<TKey, TValue>>();
}
}
internal class KeyStackDictionary<TKey, TValue>
{
// Helper dictionary to work with a stack of keys
// Usage:
// var dict = new KeyStackDictionary<int, string>();
// int[] keyStack = new int[] {23, 43, 54};
// dict.SetValue(keyStack, "foo");
// string value;
// if (dict.GetValue(keyStack, out value))
// {
// }
private DictionaryEntry<TKey, TValue> _dict;
public KeyStackDictionary()
{
_dict = new DictionaryEntry<TKey, TValue>();
}
public void SetValue(TKey[] keyStack, TValue value)
{
DictionaryEntry<TKey, TValue> dict = _dict;
for (int i = 0; i < keyStack.Length; i++)
{
TKey key = keyStack[i];
if (dict.Children.ContainsKey(key))
{
dict = dict.Children[key];
}
else
{
var child = new DictionaryEntry<TKey, TValue>();
dict.Children.Add(key, child);
dict = child;
}
if (i == keyStack.Length - 1)
{
dict.SetValue(value);
}
}
}
// returns false if the value is not found using the key stack
public bool GetValue(TKey[] keyStack, out TValue value)
{
DictionaryEntry<TKey, TValue> dict = _dict;
for (int i = 0; i < keyStack.Length; i++)
{
TKey key = keyStack[i];
if (dict.Children.ContainsKey(key))
{
dict = dict.Children[key];
}
else
{
break;
}
if (i == keyStack.Length - 1 && dict.HasValue)
{
value = dict.Value;
return true;
}
}
value = default(TValue);
return false;
}
}
You can use Linq methods too:
var array = new int[10];
var hashCode = array.Aggregate(0, (a, v) =>
HashCode.Combine(a, v.GetHashCode()));
I'm using this here
var arrayHash = string.Join(string.Empty, array).GetHashCode();
If a element changed in the array, you will get a new hash.
I would recommend:
HashCode.Combine(array)
For .NET Core 2.1 / .NET Standard 2.1 / .NET 5 and later.