❔ How can I create a fill method that creates unique elements?

I have the following 2D array method that is for basic types and references.
/// <summary>
/// Fills the array with the given value.
/// </summary>
/// <param name="value">The value to fill with.</param>
public void Fill(T value)
{
Array.Fill(m_array, value);
}
/// <summary>
/// Fills the array with the given value.
/// </summary>
/// <param name="value">The value to fill with.</param>
public void Fill(T value)
{
Array.Fill(m_array, value);
}
This works when I want basic types and every reference value pointing to the same object. I want to keep this method for those, which is the most common. However, I need a similar one that makes every element unique using new. For example, every Wall object in the array is unique. Each wall has its own properties. I do want the method generic so it allows any object of a class. Here's the idea:
/// <summary>
/// Fills the array with unique values.
/// </summary>
public void FillNew(T value)
{
for (int i = 0; i < Size; i++)
m_array[i] = new T(value);
}
/// <summary>
/// Fills the array with unique values.
/// </summary>
public void FillNew(T value)
{
for (int i = 0; i < Size; i++)
m_array[i] = new T(value);
}
Again, this is just example code of what I want to see happen, but it has a compile error that T does not have a new() constraint. Is there a good solution to this? For reference, my class is written as this:
class Array2D<T>
{
private T[] m_array;
private int m_width, m_height;
class Array2D<T>
{
private T[] m_array;
private int m_width, m_height;
15 Replies
cap5lut
cap5lut2y ago
i would just give it a a factory method:
public void Fill(Func<T> factory)
{
for (int i = 0; i < Size; i++)
m_array[i] = factory.Invoke();
}
public void Fill(Func<T> factory)
{
for (int i = 0; i < Size; i++)
m_array[i] = factory.Invoke();
}
triplemocha
triplemochaOP2y ago
@cap5lut I'm not familiar with factory methods in C#. I used your code, changed Fill to FillNew to separate it for now, and tried FillNew(new A()), and it said it can't convert A to System.Func<A>.
ero
ero2y ago
(the .Invoke() is a bit more verbose than necessary, factory() will work)
cap5lut
cap5lut2y ago
u would either have to pass a lambda expression () => new A() or pass a method:
public class Example
{
A StaticMethod()
{
return new A();
}

A InstanceMethod()
{
return new A();
}
}

blah.FillNew(Example.StaticMethod);

var o = new Example();
blah.FillNew(o.InstanceMethod);
public class Example
{
A StaticMethod()
{
return new A();
}

A InstanceMethod()
{
return new A();
}
}

blah.FillNew(Example.StaticMethod);

var o = new Example();
blah.FillNew(o.InstanceMethod);
tbh i usually dont use the short version because it sorta feels wrong reading that, u could call the parameter create or createInstance and call it the short way, but then the parameter name feels weird. personal opinion ;p
triplemocha
triplemochaOP2y ago
This compiled: map.FillNew(() => new A()); Not much luck with the InstanceMethod one.
cap5lut
cap5lut2y ago
can u show how u tried it with the instance method? and the error itself ;p
triplemocha
triplemochaOP2y ago
class A
{
public int a;

public A()
{
a = 0;
}

public static A InstanceMethod()
{
return new A();
}
}
class A
{
public int a;

public A()
{
a = 0;
}

public static A InstanceMethod()
{
return new A();
}
}
map.FillNew(A.InstanceMethod()); And Cannot convert from 'A' to 'System.Func<A>' Oh, I changed A.InstanceMethod() to A.InstanceMethod and it worked.
cap5lut
cap5lut2y ago
u r trying to execute the method, not passing the method
triplemocha
triplemochaOP2y ago
Parenthesis felt natural 🙂 I see.
cap5lut
cap5lut2y ago
yeah, no ;p also, ur InstanceMethod is a static method, not an instance one ;p instance method -> an instance for the method (this) exists. static method -> is bound to the type itself, an instance does not exist
triplemocha
triplemochaOP2y ago
The alternative would have been this, which seemed odd to create a new instance.
A a = new A();
map.FillNew(a.InstanceMethod);
A a = new A();
map.FillNew(a.InstanceMethod);
cap5lut
cap5lut2y ago
well u could have done something like
public class Factory
{
public int Min { get; set; }
public int Max { get; set; }

public A CreateInstance()
{
return new A(Random.Shared.Next(min, max));
}
}

var factory = new Factory() { Min = 10, Max = 1000 };
blah.FillNew(factory.CreateInstance);
public class Factory
{
public int Min { get; set; }
public int Max { get; set; }

public A CreateInstance()
{
return new A(Random.Shared.Next(min, max));
}
}

var factory = new Factory() { Min = 10, Max = 1000 };
blah.FillNew(factory.CreateInstance);
basically to vary some values, or even give it more complex logic
triplemocha
triplemochaOP2y ago
I see. I don't think I want a general factory class for every game class though (Wall, Floor, Cat, etc.). That can get big for my game with several CreateInstance's of each class. But at least I know several ways of doing it, and it depends on what I need of course. I'll be using all of these, I'm sure. Thanks for the help!
cap5lut
cap5lut2y ago
ignore the following if its too overwhelming: u could create a factory method factory class xD
public static class Factory
{
public static Func<Wall> CreateWallFactory(int minWidth, int maxWidth)
{
return () => new Wall(Random.Shared.Next(minWidth, maxWidth));
}
// similar for other entities
}
public static class Factory
{
public static Func<Wall> CreateWallFactory(int minWidth, int maxWidth)
{
return () => new Wall(Random.Shared.Next(minWidth, maxWidth));
}
// similar for other entities
}
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server