Argument Labels in C# - c#

Is there a way in C# to be able to refer to a a parameter by both an internal and external name (in Swift this is known as argument labels/parameters)?
What I mean is suppose I have the following:
public static class Sport
{
public static void Print(int id sportID)
{
Console.Out.WriteLine(sportID);
}
}
public static void main()
{
Sport.Print(id: 123);
}
Internally, I refer to the id as sportID, but externally, the parameter is known as id.

A little late to the game, but I was looking for something like this as well. It is not exactly what the OP is after, but I think it is close enough.
The parameter names that are set when you declare the methods can be called when calling the method.
Declaring the method:
static string[] Roster(int numberOfDaysOff, int daysOfStartOnDay) {
// Method logic with the set names
}
Calling the method:
Roster(numberOfDaysOff: daysOff,daysOfStartOnDay: startDay);
Hope this helps future readers :-)

public static void Print(int id)
{
int sportId = id;
Console.Out.WriteLine(sportID);
}
?
There's no language implicit way of aliasing the var that I'm aware of, but you can rename it by passing it to another, private function that calls it sportId, or you can assign it to a new var yourself in the function.

Not sure why you'd want to do this but here is one way:
class Parameters
{
private int _id;
public int ID
{
get { return _id;}
set { _id = value;}
}
public int SportID
{
get { return _id;}
set { _id = value;}
}
}

Related

How to create a base class/struct for value objects that validates based on super class values?

this is a problem I'm not sure how to call it or how name the things I want to do but hopefully the code examples can speak for themselves. I come from a PHP background and am learning .NET Core 2.2/3.0. Something I'm running into right now though is how I can avoid some code duplication when creating similar classes. For example I want to create multiple value objects that basically just contain strings, but each value object has different constraints. In most cases however the only constraint differences are in the length.
So in PHP I would do something like this:
abstract class Text
{
abstract public static function maxCharacters(): int;
protected $value;
public function __construct(string $text)
{
if (mb_strlen($text) > static::maxCharacters()) {
throw new LengthException(sprintf('Too many characters, the max is %d.', static::maxCharacters()));
}
$this->value = $text;
}
public function value(): string
{
return $this->value;
}
}
class Name extends Text
{
public static function maxCharacters(): int
{
return 50;
}
}
class Description extends Text
{
public static function maxCharacters(): int
{
return 1000;
}
}
It's not the best example of inheritance, but the goal is to illustrate the point in that I would like to have 1 place where I can put my validation logic, and then in the subclass only have to define the parameters of the validation and not the actual logic to perform the validation.
Since we're dealing with value objects here I assume that in C# it would be best to use a (readonly) struct. So, without any inheritance, what I ended up with as the C# equivalent is:
public readonly struct Name
{
private const int MAX_CHARACTERS = 50;
public string Value
{
get { return this.Value; }
set
{
if (value.Length > Name.MAX_CHARACTERS)
{
throw new ArgumentOutOfRangeException(String.Format("Too many characters, the max is {0}.", Name.MAX_CHARACTERS));
}
this.Value = value;
}
}
public Name(string name) => this.Value = name;
}
public readonly struct Description
{
private const int MAX_CHARACTERS = 1000;
public string Value
{
get { return this.Value; }
set
{
if (value.Length > Description.MAX_CHARACTERS)
{
throw new ArgumentOutOfRangeException(String.Format("Too many characters, the max is {0}.", Description.MAX_CHARACTERS));
}
this.Value = value;
}
}
public Description(string description) => this.Value = description;
}
But as you can see without inheritance that's a lot of copy/paste, and copy/paste is something I prefer to avoid. The only alternative I could think of is to create a separate TextValidator class or something that I can call from the set to which I would only have to pass the max number of characters, but that would still leave me with more copy/paste than I'd prefer.
How would you write something like this in C# with as little copy/paste as possible?
It seems like you've got the basics of inheritance understood in your PHP example; I'd just suggest doing a bit of reading on the syntax in C#.
For what it's worth, the following would do the trick:
public abstract class Text{
public string Value { get; }
public Text(string val) {
if (val.Length > MAX) throw new Exception();
Value = val;
}
protected abstract int MAX{get;}
}
public class Name : Text{
public Name(string val): base(val) { }
protected override int MAX => 50;
}
public class Description : Text
{
public Description(string val) : base(val) { }
protected override int MAX => 1000;
}
I'll also add a footnote to say be careful calling abstract methods/properties from a class constructor (which is what I'm doing here). If, for example, the value of MAX is a computed value which depends on the object already having been initialized, you could run into some issues. In this case though, it won't be a problem.

Assign different types of variable to one type

As a very simplified and stupid example of what I'm dealing with, suppose I had the following class with a simple static int property:
public class MyClass
{
public static int MyVar { get; set; }
}
So, if I wanted to set that property via code, it would be easy enough with something such as:
MyClass.MyVar = 2;
But, how could I take care of (again, to simplify the example) passing in a string and have it converted to an int?
The only way I could think of doing it is to create a helper method such as:
public class MyClass
{
public static int MyVar { get; private set; }
public static void SetMyVar(string sMyVar)
{
MyVar = int.Parse(sMyVar);
}
}
And then in code run:
MyClass.SetMyVar("2");
I would love to know if there was a better way to accomplish this than having to add in that extra method.
Although you definitely shouldn't do this because it's confusing to read, you could create the property this way
class MyClass
{
private static int _property = 0;
public static object Property
{
get
{
return _property;
}
set
{
_property = Convert.ToInt32(value);
}
}
}
You would have to cast this to an int whenever you wanted to use it as an integer but this is best I could think of.
is this what you were trying to do?
class newclass
{
private static int MyVarValue = 0;
public static int MyVar
{
get;
set
{
MyVarValue = Convert.ToInt32(value);
}
}
}
This would not compile because the value that a property gets set to has to be of the same type as the property itself. But if you are taking a list of objects in a constructor and assigning them to the properties, there you can do something like this...
class newclass
{
private static int MyVarValue = 0;
public newclass(List<object> startingList)
{
MyVarValue = Convert.ToInt32(startingList[0]);
}
}
You can use the compiler's method overload resolution to pick a SetMyValue method depending on the type of the argument. Inside each SetMyValue method you have a mechanism to convert all of the different input values to the same underlying type.
Doing this is probably a bad idea - but here goes anyway. It doesn't have quite the semantics that you're asking for but it's close:
//A class with multiple 'set' methods that will silently handle
//type conversions
class MyClass{
private int myValue;
public int MyValue { { get return this.myValue; } }
public void SetMyValue(int value){
this.myValue = value;
}
public void SetMyValue(string value){
this.myValue = Convert.ToInt32(value);
}
}
In statically typed languages, switching types silently in a way that loses information is not a very wise idea. There are other, dynamically typed languages that let you play fast and loose with types but C# is not one of them. You have to go out of your way in C# to get dynamic typing.
Doing this is probably a pain in the butt from a maintenance standpoint. I would put some more thought into the underlying problem that you're trying to solve that lead to this question.

Property setter not accessed when the property changed by external class

I have a public class that is is used to create a dll. It has a variable and a property. Let`s assume it looks like this:
public class Main
{
private int _someInt = 0;
public int SomeInt
{
get { return this._someInt; }
set
{
this._someInt = value;
if (this._someInt == 1)
{
_someInt = 0;
}
}
}
public int ExecuteMain()
{
OtherClass.DoSomething(this.SomeInt);
}
}
I also have another class, in a separate project in the OtherClass class, that has the static DoSomething method:
public static void DoSomething(int someInt)
{
someInt = 1;
}
My problem is that SomeInt property in the Main class is getting set to 1 by the DoSomething method of OtherClass, but this does not trigger the setter in the Main class' property. Am I doing something wrong?
What you are doing is passing SomeInt by value to the DoSomething method, which gets a copy of the int and just changes its local value.
You can:
Pass by ref: public static void DoSomething(ref int someInt)
Pass the Main class and change the value inside DoSomething:
public static void DoSomething(Mainclass main)
{main.SomeInt = 1}
There is no way of doing this,even if you pass the field by reference using ref keyword it's not gonna work because your property has a setter method not your field.You should be changing the value of your property, in order to execute the setter method and perform the validation.
You can do that,passing the current instance of your class instead of the field, for example:
public int ExecuteMain()
{
OtherClass.DoSomething(this); // just pass current instance using 'this'
}
public static void DoSomething(Main obj)
{
obj.SomeInt = 1;
}
If you want to have it invoke the setter logic, one option is to do something like this:
public static void DoSomething(Action<int> setSomeInt)
{
setSomeInt(1);
}
then call it like this:
public int ExecuteMain()
{
OtherClass.DoSomething(x => this.SomeInt = x);
}
The concept here is that what you're really giving the method is not a variable that can be set, but rather an action that can be performed. This is an important distinction, as setting a property is really a kind of action, which can have an arbitrarily complex implementation. This approach is a bit awkward in practice, though, so you'll want to think carefully about what you're really trying to do here and whether there's a better way to express the desired dependency.

C# Do something after a void is loaded

I try to use data after I downloaded it from an API. Example of my code:
private int id;
public MainPage()
{
InitializeComponent();
SomeFunction();
}
public void SomeFunction()
{
DownloadFromAPI("url to api");
MessageBox.Show(id.ToString()); //<< Returns 0
}
public void DownloadFromAPI(DownloadStringCompletedEventArgs url)
{
//code to retrieve data (singel id)
id = Int16.Parse(data);
MessageBox.Show(id.ToString()); //<< Returns the correct number, like 14
test();
}
private void test()
{
MessageBox.Show(id.ToString()); //<< Even Returns the correct number 14
}
How is it possible to load the id information after DownloadFromAPI("url to api"); is finished. so i get the right number (14) instead of 0?
I suspect your method actually looks like this:
public void DownloadFromAPI(...)
{
int id = Int16.Parse(data);
MessageBox.Show(id.ToString()); //<< Returns the correct number, like 14
}
That's declaring a new local variable within the method, rather than assigning a value to the instance variable.
However, personally, I'd often prefer to write the method to return the value instead:
public int DownloadFromApi(...)
{
return Int16.Parse(data);
}
Of course if this really is natural state within the object, it may make sense - but often it can be simpler to write code which just computes a value and returns it, than getting into mutation territory.
Whether you keep the 'id' in a local class member or not, either way, you should generally have your methods act upon input and produce any pertinent output, without referencing things outside of their local stack. I would go with something like the following:
public MainPage()
{
InitializeComponent();
SomeFunction();
}
public void SomeFunction()
{
int id;
DownloadFromAPI("url to api", out id);
MessageBox.Show(id.ToString());
}
public void DownloadFromAPI(url, out int id)
{
//retrieve data...
// set id...
id = Int16.Parse(data);
}

Chain-overloading constructors?

I'm trying to build a class which will initalise its self either by passing in a reference to a record in a database (with the intention that a query will be run against the database and the returned values for the objects properties will be set therein), or by specifying the values "by hand" - this no database call is required.
I've looked at a couple textbooks to discover the "Best-practice" for this functionality and sadly I've come up short.
I've written a couple sample console apps reflecting what I believe to be the two most probable solutions, but I've no Idea which is the best to implement properly?
Sample App #1 uses what most books tell me is the "preferred" way but most examples given alongside those claims do not really fit the context of my situation. I'm worried in here that the flow is not as readable as App #2.
using System;
namespace TestApp
{
public class Program
{
public static void Main(string[] args)
{
var one = new OverloadedClassTester();
var two = new OverloadedClassTester(42);
var three = new OverloadedClassTester(69, "Mike", 24);
Console.WriteLine("{0}{1}{2}", one, two, three);
Console.ReadKey();
}
}
public class OverloadedClassTester
{
public int ID { get; set; }
public string Name { get; set; }
public int age { get; set; }
public OverloadedClassTester() : this(0) { }
public OverloadedClassTester (int _ID) : this (_ID, "", 0)
{
this.age = 14; // Pretend that this was sourced from a database
this.Name = "Steve"; // Pretend that this was sourced from a database
}
public OverloadedClassTester(int _ID, string _Name, int _age)
{
this.ID = _ID;
this.Name = _Name;
this.age = _age;
}
public override string ToString()
{
return String.Format("ID: {0}\nName: {1}\nAge: {2}\n\n", this.ID, this.Name, this.age);
}
}
}
This Sample (App #2) "appears" more readable - in that I think it's easier to see the flow of operation. However it does appear efficient in terms of characters saved :p. Also, is it not dangerous that it calls a method of the object before it's fully initialised, or is this not a concern?
using System;
namespace TestApp
{
public class Program
{
public static void Main(string[] args)
{
var one = new OverloadedClassTester();
var two = new OverloadedClassTester(42);
var three = new OverloadedClassTester(69, "Mike", 24);
Console.WriteLine("{0}{1}{2}", one, two, three);
Console.ReadKey();
}
}
public class OverloadedClassTester
{
public int ID { get; set; }
public string Name { get; set; }
public int age { get; set; }
public OverloadedClassTester()
{
initialise(0, "", 21); // use defaults.
}
public OverloadedClassTester (int _ID)
{
var age = 14; // Pretend that this was sourced from a database (from _ID)
var Name = "Steve"; // Pretend that this was sourced from a database (from _ID)
initialise(_ID, Name, age);
}
public OverloadedClassTester(int _ID, string _Name, int _age)
{
initialise(_ID, _Name, _age);
}
public void initialise(int _ID, string _Name, int _age)
{
this.ID = _ID;
this.Name = _Name;
this.age = _age;
}
public override string ToString()
{
return String.Format("ID: {0}\nName: {1}\nAge: {2}\n\n", this.ID, this.Name, this.age);
}
}
}
What is the "correct" way to solve this problem, and why?
Thanks,
I would definitely chain the constructors, so that only one of them does the "real work". That means you only have to do the real work in one place, so if that work changes (e.g. you need to call some validation method at the end of the constructor) you only have one place where you need to change the code.
Making "simple" overloads call overloads with more parameters is a pretty common pattern IME. I find it more readable than the second version, because you can easily tell that calling one overload is going to be the same as calling the "bigger" one using the default values. With the second version, you have to compare the bodies of the constructors.
I try not to have more than one constructor which chains directly to the base class wherever possible - unless it's chaining to a different base class constructor, of course (as is typical with exceptions).
Do not use database calls in a constructor. This means your constructor is doing a lot of work. See http://misko.hevery.com/code-reviewers-guide/ (Google guide for writing testable code).
Apart from this, chaining constructors (option 2) looks good. Mostly because as you say it is readable. But why are you assigning this.Name etc in the constructor and doing it again in initialize. You could assign all values in initialize.
Maybe something like this?
public class OverloadedClassTester
{
public int Id { get; private set; }
public string Name { get; private set; }
public int Age { get; private set; }
public OverloadedClassTester (Person person)
: this (person.Id, person.Name, person.Age) { }
public OverloadedClassTester(int id, string name, int age)
{
Id = id;
Name = name;
Age = age;
}
public override string ToString()
{
return String.Format("Id: {0}\nName: {1}\nAge: {2}\n\n",
Id, Name, Age);
}
}
maybe it would be better to use optional parameters? In this case, you would create a single constructor and initialize the values to the parameters you wish to set.
More information: link text
I prefer #1, the chaining constructors, from a maintenance perspective. When someone comes back to edit the code later on, you wouldn't want them to edit the initialise() method and not realize that it is being called from a constructor. I think it is more intuitive to have all the functional parts in a constructor of some kind.
Personally, I use constructor chaining like that all the time.

Categories

Resources