I am making a game in C#, where you have ammo and a max capacity of it.
Is it possible to make some kind of method like this
ammoInt.Maxed;
so that i can use it like this:
if (ammoInt.Maxed == true) etc.
to check if ammo int is equal to maxAmmoInt?
EDIT:
Thank you for the input, but one last question: do the extension have to be in a seperate class?
You can create an Extension method for int. Like:
public static class MyExtensions
{
public static bool Maxed(this int parameter)
{
return parameter > 100;
}
}
Then you can call it like:
if(ammoInt.Maxed())
Technically, yes. Extension methods provide this in .Net. But this is bad design.
public static class MyExtensions
{
public static public bool IsMaxed( this int value )
{
return value > 50; // or whatever
}
}
int thing = 10;
bool result = thing.IsMaxed( );
This allows you to call that method on any int object. But like I said, you should probably reconsider the design of that, as that is a hack.
The way that I see it is that you have two options.
1) Create a wrapper class that has a bool property that check if its value if greater than 100
public class Ammo
{
public int Value {get; set;}
public bool Maxed
{
get
{
return Value > 100;
}
}
}
2) You can create an Extension Method
public static class CustomExtensions
{
public static bool Maxed(this int value)
{
return value> 100;
}
}
Related
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.
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;}
}
}
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.
I have class like bellow and I want to only let x be changed in Foo method and no other property. I can't use [Pure] like following example, because it locks all properties:
public class Test
{
private int x,y,z; //number of these properties is large
[Pure]
public void Foo()
{
//only x must be allowed to change
}
}
and I don't want to use something like this for all other properties than x:
Contract.Ensures(Contract.OldValue<int>(y) == y);
Contract.Ensures(Contract.OldValue<int>(z) == z);
...//and for other large number of properties
Is there any way to do this?
Unfortunately, standard way with Contracts I'm not found.
But you may use this way (this way have some constraints):
public class Test
{
public int x, y, z;//....
public void Foo()
{
x = FooBody();
}
[Pure]
private int FooBody()
{
int value = x;
//work with value as x
return value;
}
}
It seems there is no method implemented for this purpose in Contract 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.