C# type argument constraints - c#

I'm trying to do something a certain way... but I'm certain there's a better way
public interface IMix
{
T Mix<T>(List<T> values) where T : IMix;
}
The problem with this is that if I want to "Mix" 5 values, then I need to do value1.Mix(others) but that is not clean. Plus, the type of T needs to be the same type as whatever class implements the interface. So, this doesn't really work.
I was thinking something like this:
public static class MixWrapper
{
public static T Mix<T>(List<T> values);
}
But that obviously won't work because I have to define the body in MixWrapper
EDIT: to clear up some misunderstanding, these are not real math averages, I could just as easily say "Fuse" or anything else. For example I could be trying to "average" a list some struct or other class.
EDIT 2:
One example could be a class like this
class Sequence : IMix
{
List<int> sequence;
double period;
double weight;
}
The "Mix" in this case would need to return a Sequence that was built this way: the resulting period is the weighted average of the periods based on the weight. The weight is the sum of the weights, and the sequence is the weighted average of the sequences after they have been timescaled down to the resulting period. Suffice to say, any complicated method that you could think of needs to be accounted for

If you want to calculate average of some list, then you can use LINQ:
var value = list.Average(x => x.SomeProperty);

Put the type T on your interface and just fill it with the same type as the class when you're implementing it:
public interface IMix<T>
{
T Mix(List<T> values);
}
public class ConcreteObjects : IMix<ConcreteObjects>
{
public ConcreteObjects Mix(List<ConcreteObjects> values)
{
// do mixing
}
}
This also leaves the door open for other classes to be able to mix ConcreteObjects if need be.

I think you're looking for an extension method.
You need to define a static method somewhere (some helper class, I suppose) like this:
public static T Average<T>(this List<T> list) where T : IAverage
{
return // average stuff
}
Now you just need to include your helper class with using and you can do something like this:
AverageClass implements IAverage
List<IAverage> list = new List<AverageClass>();
var average = list.Average();

Related

How to have type-safety dependent on a number? (like generics are dependent on a Type)

I want a Type that is "for" a certain number, and another Type for another number. But I don't want to have to manually define a Type for each number like Level1024 and Level1000. I want it to be simple to instantiate an instance of the Level class for each number, like we can do with generics where we can create a Level<string> and a Level<int> without needing to define a separate Level for each of them.
Here's the idea:
Level<1024> topPlayerOf1K;
Level<1000> Abe = new Level<1000>();
topPlayerOf1K = Abe; //This should show a squiggly line in Visual Studio.
How can I achieve that or something like that?
Numbers literals are not considered types in C# like they are in TypeScript, and cannot be used as generic parameters like template parameters in C++.
At the minimum you would have to create types for each of the number literals you want to use. The approach could look like this:
interface IConstantInt { int Value { get; } }
class ConstantInt1000 : IConstantInt { public int Value => 1000; }
class ConstantInt1024 : IConstantInt { public int Value => 1024; }
class Level<TConstantInt> where TConstantInt : IConstantInt { }
var level1000 = new Level<ConstantInt1000>();
var level1024 = new Level<ConstantInt1024>();
It would be good to autogenerate this code if you're going to have many of those. This is not a great solution, but without knowing more about your program and what kind of errors you're trying to prevent, in the abstract, that's a way that you could encode number literals in the type system.
Edit: here's one way that you could access the value inside the class:
class Level<TConstantInt> where TConstantInt : IConstantInt
{
readonly int _intValue;
public Level(TConstantInt constantInt) =>
_intValue = constantInt.Value;
}
class Level
{
// Optional utility factory method, helps with type inference
public static Level<TConstantInt> Create<TConstantInt>(TConstantInt constantInt)
where TConstantInt : IConstantInt =>
new(constantInt);
}
// Now creation looks like this:
var level1000 = Level.Create(new ConstantInt1000());
var level1024 = Level.Create(new ConstantInt1024());

How to sort a List<> that contains derived class objects, by derived class method

I have a double problem here. I need to sort a List<> that I know contains objects of a derived class to the class that the list was declared to contain originally. AND, I need to sort by the return value from a method in that derived class, which takes a parameter. Keep in mind that I already know the List contains objects all of the derived class type.
I've created some sample code here to demonstrate the question since the real code cannot be shared publicly. Note, I have no control over the base conditions here (i.e. the fact that the List<> collection's declared contents are the parent class and that it contains objects of the derived class, which contains a method that takes an argument and returns the values that I need to sort the collection by). So, I doubt I'd be able to use any suggestion that requires changes there. What I think I need is a way to specify (cast?) what is really in the List so I can access the method defined there. But I'm open to other thoughts for sure. Otherwise I'm left with a traditional bubble sort. Thanks.
public class Component
{
public int X;
public int Y;
}
public class ComponentList : List<Component>
{
// Other members that deal with Components, generically
}
public class Fence : Component
{
public int Distance(int FromX, int FromY)
{
int returnValue = 0;
// Caluclate distance...
return returnValue;
}
}
public class Yard : Component
{
// Yada yada yada
}
public class MyCode
{
public List<Component> MyFences;
public MyCode(List<Component> Fences, int FromX, int FromY)
{
// Sort the fences by their distance from specified X,Y
Fences.Sort((A as Fence, B as Fence) => A.Distance(FromX, FromY).CompareTo(B.Distance(FromX, FromY)));
// Or
List<Fence> sortedFences = MyFences.OrderBy(A => A.Distance(FromX, FromY)).ToList();
// Or ???
}
}
Use the Enumerable.Cast<Fence> extension method to transform your IEnumerable<Component> to IEnumerable<Fence>. Then I'd use your second approach (the OrderBy approach) to sort it, but that's my preference.
List<Fence> sortedFences = MyFences.Cast<Fence>().OrderBy(A => A.Distance(FromX, FromY)).ToList();
This approach will throw if there is an object in MyFences that can't be cast to Fence. If you expect that the code should only be passed Fences, this might be what you want. If, instead, you want to skip over non-Fence members, you can use:
List<Fence> sortedFences = MyFences.OfType<Fence>().OrderBy(A => A.Distance(FromX, FromY)).ToList();

Creating a Many to One Class Relationship

I have a set of class objects that I can not touch. All of them have an ID property that I would like to access in other functions in a generic way.
For simplicities sake here is an example of my problem.
class Example1 {
int ID { get; set;}
}
class Example2 {
int ID { get; set; }
}
I am not able to edit either of these two classes or the library they are in.
I also have a function that expects an ID that can come from either Example1 or Example2. In order to handle this I have come up with a number of solutions but am curious what the proper way to solve this would be.
I could:
Use dynamic classes to access the various classes ID's.
Use reflection to pull out an ID parameter from any given type.
Use an odd inheritance by creating a new class so that Example1ViewModel : Example1, IIdentifiableObject and then expect IIdentifiableObject in my function and implement a copy constructor in Example1ViewModel to handle collecting the data
Write a separate filter function that can extract out the relevant parts from either class and provide the results.
None of these solutions seem particularly good to me. How should I be handling a many to one relationship like this in code and are there tools that C# provides to handle this?
possible solution using extension methods for the classes
public static class MyExtensions
{
public static int GetId(this Example1 ex)
{
return ex.Id;
}
public static int GetId(this Example2 ex)
{
return ex.Id;
}
}
You can add a static method using reflection:
public static int GetId(object obj)
{
Type type = obj.GetType();
return Convert.ToInt32(type.GetProperty("ID").GetValue(obj, null));
}
Then you can invoke it with any object to get the id property value.
Here is the solution that we ended up using and why.
We are using an inheritence structure that that takes the following two base classes:
FooExample
BarExample
and wraps them in the following
IExample
FooExampleModel : IExample
BarExampleModel : IExample
Both FooExampleModel and BarExampleModel have constructors which accept the class they are wrapping.
The importance of this is that it allows us to create methods accepting IExample instances without having to manipulate data beforehand. Additionally, unlike using dynamic types or reflection this solution provides us with compile time error checking.
Unfortunately using extension methods does not work. While it allows us to call the same method on two different object types like we wanted it does not allow those objects to be passed as Generic types to a seperate function.
The result of all of this is that this is now possible:
var foos = new List<FooExample>(); //Pretend there is data here
var bars = new List<BarExample>();
var examples = foos.Select((foo) => (IExample)new FooExampleModel(foo))
.Concat(bars.Select((bar) => (IExample)new BarExampleModel(bar)))
.ToList(); // Force evaluation before function call
DoSomethingOnIExamples(examples);
Besides that slightly gross LINQ query this appears to be the best way to accomplish this (DoSomethingOnIExamples(...) is a function accepting an IEnumerable<IExample> argument). Obviously this solution gets less nice as more types are added to this mix.

How to access properties from an array of class objects in C#?

Character[] PlayerOne = new Character[5];
PlayerOne[1] = new BladeWarrior();
PlayerOne[2] = new FistWarrior();
PlayerOne[3] = new Archer();
PlayerOne[4] = new RedMage();
PlayerOne[5] = new BlueMage();
I know through polymorphism, a BladeWarrior can be a Character but it cant be the other way around. My problem is that when I try to access an element of an array. Player[1] for example, I cant access functions and variables from the BladeWarrior class. It's only letting me access variables and functions from the Character class which the BladeWarrior class inherits from.
I'm going to need to be able to access Bladewarrior functions/variables if Im going to want 2 characters to fight.
I was thinking I could use the "as" function to set PlayerOne[1] as the specific object . Not exactly like this:
string s = objArray[i] as string;
The line of code above is just to get an idea of which "as" Im talking about.
What is a solution to this problem?
I'm going to need to be able to access Bladewarrior functions/variables if Im going to want 2 characters to fight.
It looks like you are attempting to do a multiple dispatch: you want the call of
Fight(PlayerOne[i], PlayerOne[j]);
to call a function that knows the exact types of both characters. There are different tricks that you can use to achieve double dispatch in single dispatch languages, most notably, the visitor pattern. Starting with C#4, you could also use dynamic to implement double dispatch in a relatively clean and easy to read way:
static class FightArena {
public static void Fight(dynamic a, dynamic b) {
try {
DoFight(a, b);
} catch {
Console.Error.WriteLine("{0} and {1} cannot fight", a, b);
}
}
private static void DoFight(BladeWarrior a, Archer b) {
}
private static void DoFight(BladeWarrior a, FistWarrior b) {
}
private static void DoFight(BladeWarrior a, RedMage b) {
}
private static void DoFight(BladeWarrior a, BlueMage b) {
}
private static void DoFight(BladeWarrior a, BladeWarrior b) {
}
private static void DoFight(Archer a, Archer b) {
}
... // Enumerate all pairs that can fight
}
Now you can write something like this:
FightArena.Fight(PlayerOne[i], PlayerOne[j]);
and the call will reach the exact pair of types based on dynamic types of PlayerOne[i] and PlayerOne[j].
If you have to cast your Character's back to their concrete types for them to fight you are loosing any benefit you would get from polymorphism. If you need to cast to a Character to a Bladewarrior to fight that means you have to write different logic to each character to be able to fight each other. Then if you later add a new character type you'll have to update all of your fight code to support that type.
What you really want to be able to do is to write a generate fight algorithm that can be used to fight any two Character objects without casting them. You could add properties to the Character base class that would indicate the properties that the character has.
For example you could have add a Attacks property to the Character class which would be a list of the attacks the character has which would have a name of the attack and how much damage it does. Then each derived character class would populate its list of Attacks and your fight algorithm would process these attacks. In this way each character could have its own list of attacks, but would not have to be cast to a specific character type to access it.
The end goal here is for any external code to only know about the Character class and not any of its derived classes. That will make your external code cleaner and give you the ability to add or remove character classes in the future.
It is absolutely normal,if you want access BladeWarrior's properties you must convert your Character to BladeWarrior, and you'r right you can use as keyword for this:
BladeWarrior bw = PlayerOne[1] as BladeWarrior;
You are upcasting the instances thats why you are only able to use parent class behaviours and attributes.
I think you will have to do i individually for all instances.
BladeWarrior player1 = new BladeWarrior();
FistWarrior player2 = new FistWarrior();
Archer player3 = new Archer();
//and so on
As you said you can use "as" to cast. If the instance you are trying to cast cannot be casted to the target class you will get an null.
var currentCharacter = PlayerOne[1] as BladeWarrior;
if(currentCharacter != null)
{
....
}
The challenge here is to get a clean way to know what is the right casting.
May be you could use a structure in the array and use a flag to indicate the underliying class
switch(PlayerOne[1].Type)
{
case PlayerTypes.BladeWarrior:
currentCharacter = PlayerOne[1].Character as BladeWarrior;
}
But in general it seems you are not acomplishing the Liskov Subtitution Principle (The L in SOLID principles). You shouldnt need to access to the implementation details of the specific types of characters, Just override some methods or use a more modular(and complex) design based on the strategy pattern.
or you can use interface
public interface ICharacter {
int myValue { get; set;}
void myMethod();
}
public class BladeWarrior : ICharacter {
private int myPrivateValue;
public int myValue { get { return myPrivateValue; } set { myPrivateValue = value; } }
public void myMethod() {
//Do what you want
}
}
ICharacter[] PlayerOne = new ICharacter[5];
PlayerOne[0] = new BladeWarrior();
then you can access your interface methods
ICharacter[0].myMethod();

Inheriting a List<> in c# and overriding the constructor

I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.
I start with
public struct datum {
public UInt32[] chan;
public UInt64 sample_number;
public UInt32 time;
public UInt32 source_sector;
}
public class dataSet : List<datum> {
bool dirty=true;
....
}
the methods are typically like this (I want to know if the list has been modified as I have a max()/min() function that only parses the data when it has been modified and caches the values to reuse if the List has not been modified)
public new void Add(datum x ) {
base.Add(x);
this.dirty = true;
}
However, I'm not sure how to create a constructor. This syntax does not work.. how can I get this type of behavior?
public dataSet(int count) {
this = (dataSet) new List<datum>(count);
}
I also have this constructor, which seems to work fine (no compilation errors) though untested
public dataSet(List<datum> data) {
this.AddRange(data);
}
I came across a post that said that you should use a Collection and a List is used for speed. Though I need the speed, and I'm not sure why a Collection would be better?
--UPDATE--
I don't want to use linq as you can't create something that computes max/min simultaneously as efficiently as this:
public void recalculateMaxMin() {
foreach (var d in data) {
for (int i = 0; i < 16; i++) {
if (d.chan[i] > max[i]) max[i] = d.chan[i];
if (d.chan[i] < min[i]) min[i] = d.chan[i];
}
}
}
Thnx
I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.
Don't. Just use LINQ to Objects. That's what it was designed for:
var list = new List<int> { 10, 20, 30 };
var average = list.Average();
var max = list.Max();
// etc
In general, I would advise against deriving from List<T> anyway - that's not what it was designed for. However, if you must, you just chain from one constructor to a base constructor:
public dataSet(int count) : base(count)
{
// Add in any extra code you want to here. Probably none in this case.
// It would execute *after* the base constructor call.
}
See my article on constructors for more information about constructor chaining.
(I'd also strongly advise you to change the name - dataSet doesn't comply with .NET naming conventions, and DataSet would mean something else entirely to most .NET developers.)
You can never ever set "this" to something in C#. I think you are looking for this:
public dataSet(int count)
: base(count)
{ }
However in my opinion you should take a look at "System.Linq" namespace. I think what you are trying to implement has been done before by Microsoft. 'Select', 'Join', 'Where' and many other clauses has been already implemented in Linq. Also you can use "INotifyCollectionChanged" interface to implement the dirty thing.
Here are some references:
INotifyCollectionChanged
Linq
If you realy need to implement a complete List class with a new behavior, implementing "System.Collections.Generic.IList" interface is the only thing that will rock your idea in an advanced and perfect way. It's more customizable than inheriting from the List class and trying to change everything you have no access to.
Hope it helps
Cheers
public dataSet(int count)
: base(count) {
}
You can call the base type's constructor using base()
public dataSet(int count) : base(count)
{
// no need to implement anything here. base(count) will call the base
// type's constructor
}

Categories