The Dink Network

Overthinking it

February 13th 2019, 07:20 PM
duck.gif
toof
Peasant He/Him
I disagree. 
Does anyone here have experience with C#? I kinda need(?) some help. I'm asking C# specifically, cause it's related to usage of some specific classes, and the problem that I'm having is not related to any rational coding stuff. It's just... well... overthinking it... A can this be done, although it's totally idiotic kinda thing
February 14th 2019, 03:07 PM
dinkdead.gif
Um, a bit, yes. I'm mostly curious what your question is
February 14th 2019, 03:29 PM
slimeg.gif
metatarasal
Bard He/Him Netherlands
I object 
I should know some things.
February 14th 2019, 05:02 PM
duck.gif
toof
Peasant He/Him
I disagree. 
Just a reminder, not that important, don't bang your heads too hard

I'll keep it simple, then build on (ignore potential issues). Suppose you have a class Human with two properties:
class Human
{
  public string Name {get; set;}
  public int Age {get; set;}
}

When I instantiate that class, I wanna do it by using lambda expression that will set parameters to call certain functions within that class, which determine whether the input (set) is acceptable or not... Phew

Again, keeping it simple, let's say that if someone wanna set Human's age to 137, he can't do that because there's a limit. I'm aware that the class has no implementation for that yet.
So the constructor should look like this:
var human = new Human(cfg =>
  cfg.Age.MaximumAge = 70,
  cfg.Age.MinimumAge = 0
);


The values of minimum and maximum age can be a field, or properties of a nested class within Human.

If I also wanna be able to implement some restrictions to Name property, I'll add a function that will be called when setting the Name property. Some regular expression that will filter out strings containing characters or numbers. Don't worry about the function itself, just how to get this lambda to work.

var human = new Human(cfg =>
  cfg.Age.MaximimumAge = 70,
  cfg.Age.MinimumAge = 0,
  cfg.Name.ContainSymbols = false,
  cfg.Name.ContainNumbers = true
);


Use nested classes, delegates, whatever... If this has no solution, the other thing I'll accept as a replacement is some class, say... Factory. So you can pass any generic class to it, and do the same as above.

var crap = new Factory<Human> (cfg =>
  cfg.Name.ContainSymbols = false
  // etc
);


I know this post is a bit messy. If anything remained unclear, ask... Bottom line, make a class where restrictions on property values are defined in a constructor, via lambda expression...
February 14th 2019, 06:31 PM
slimeg.gif
metatarasal
Bard He/Him Netherlands
I object 
What you're really trying to do is to change the class-definition at run time. The moment you add methods to the Human class it isn't really a Human class anymore, but some derived type. In some weakly typed languages (e.g. JavaScript) you can change class definitions all the time at your leisure (so you have no idea what kind of object you are really working with), C# is a bit more strict.

The real question is what kind of problem this is trying to solve. If maximum age is a property of the Human class it should be implemented in the Human class and the Human class should have the responsibility to do the checking. If you don't have access to the Human class (because it is defined in some dependency or something) you should inherit it. If you can't change the base class and you can't inherit it you won't be able to do much because then the entire implementation is sealed. That's basically the author of the class saying 'this is what a Human is, and that's that'.

If you desperately want to do it through lambda expressions there is a way... Try this, for restricting the Age property:

public class Human
{
    private Func<int, bool> _ageRestriction;

    public string Name { get; set; }

    private int _age;
    public int Age
    {
        get { return _age; }
        set
        {
            if (_ageRestriction.Invoke(value))
                _age = value;
            else
                throw new ApplicationException("A wrong value was just passed, we shall throw an exception...");
        }
    }

    public Human(Func<int,bool> ageRestriction)
    {
        _ageRestriction = ageRestriction;
    }
}


Now you can parse a lambda-expression containing the age-restriction you want to pass to the human class like this:

Human human = new Human(ageRestriction: x => x <= 70 && x >= 0);
human.Age = 65;  //This is fine.
human.Age += 10; //This throws an exception.


Still, I think making minimum and maximum age a property of the Human class is the more semantically correct way to go about this, even though this is possibly a bit more generic.

EDIT: Wow, the code tags somehow put a semicolon after &&. I promise that isn't me doing that...
February 14th 2019, 07:50 PM
duck.gif
toof
Peasant He/Him
I disagree. 
Not bad... Not bad indeed. Not quite what I wanted, but it's close

The real question is what kind of problem this is trying to solve. If maximum age is a property of the Human class it should be implemented in the Human class and the Human class should have the responsibility to do the checking.

I don't really like quoting myself, I just love it
not related to any rational coding stuff

On a more serious note, although I still don't have any real example, suppose you have some enumerator that must determine on a specific place what age range should be allowed. So, instead of regular if you create a new object that handles whether the input is right or wrong. This is an overkill, sure, and there are much simpler ways to do it, but I was just curious.

By the way, how the duck did you deduced that Invoke() should take value as a parameter??? I was ready to smash my laptop at some point...

Edit:
plus, that whole:
ageRestriction: x => x <= 70 && x >= 0 in the constructor...
I'm kinda new to this... TDN is weird. Really, really weird.
February 14th 2019, 08:09 PM
dinkdead.gif
Baphomet
Peasant He/Him
I Like War. 
My face hurts reading all this programing. Lol