This question already has answers here:
Calling constructor from other constructor in same class
(3 answers)
Closed last month.
I know about "This" keyword and what is it working. but what is this using for?
public ReactiveProperty() : this(default(T))
{
}
I have seen this in UniRx Project. I just don't know the "This" keyword front of constructor.
I googled it but there is nothing to catch.
does anyone know?
This syntax is used to call another constructor defined in the class. Example from the docs:
class Coords
{
public Coords() : this(0, 0) // calls Coords(int x, int y) with x = 0 and y = 0
{ }
public Coords(int x, int y)
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
public override string ToString() => $"({X},{Y})";
}
var p1 = new Coords();
Console.WriteLine($"Coords #1 at {p1}");
// Output: Coords #1 at (0,0)
var p2 = new Coords(5, 3);
Console.WriteLine($"Coords #2 at {p2}");
// Output: Coords #2 at (5,3)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have the class Pos:
public class Pos
{
int x;
int y;
public int X
{
get
{
return x;
}
set
{
try
{
if (value == 3)
{
x = value;
}
}
catch
{
throw new ArgumentException();
}
}
}
public int Y { get; set; }
public Pos(int x, int y)
{
X = x;
Y = y;
}
}
I have an instance created, with X = 0. That is, as far as I understand, in the case of value = 3 -> x = 0 and in the constructor X = 0, then create an instance of the class.
How do I prevent an instance of a class from being created when the x property setter fails?
I will create a List that should not contain "wrong" objects.
I am having a lot of difficulty understanding what this code is supposed to do and how the question relates to it, but I think maybe you are asking "how do I validate the correctness of the arguments to property setters?"
Follow this pattern:
// Class names should be words, not abbrvtns like "Pos"
public class Position
{
private int x;
private bool IsValidX(int possibleX)
{
// Here return true if possibleX is valid, false otherwise
}
public int X
{
get { return this.x; }
set
{
if (!IsValidX(value))
throw new ArgumentException("explanation here", "value");
this.x = value;
}
}
// Now do the same thing for Y.
public Position(int x, int y)
{
if (!IsValidX(x))
throw new ArgumentException("explanation here", "x");
if (!IsValidY(y))
throw new ArgumentException("explanation here", "y");
this.x = x;
this.y = y;
}
}
Notice that we want to throw different argument exceptions because the argument names are different in each case.
This question already has answers here:
CS0120: An object reference is required for the nonstatic field, method, or property 'foo'
(9 answers)
Closed 5 years ago.
First i'll give you a run around my code,
I have a class that stores some data :
public class Balta
{
public int x;
public int y;
public int raza;
public int cantApa;
public int id;
public int intersect;
public Balta(int xs, int ys, int r, int cApa, int ids, int intersctt)
{
x = xs;
y = ys;
raza = r;
cantApa = cApa;
id = ids;
intersect = intersctt;
}
}
Secondly I have a class that makes a list of that data and stores it acordingly,also i intend to do some operations with that data once i get rid of this pesky error.
public class Baltile
{
public int n;
List<Balta> balti = new List<Balta>();
public void populate(Balta balta)
{
int unitId = balta.id;
if (balti.Any(Balta => Balta.id == balta.id))
{
int pos = balti.FindIndex(Balta => Balta.id == balta.id);
balti[pos] = balta;
}
else if (balti.Any(Balta => Balta.cantApa == -1) && !balti.Any(Balta => Balta.id == unitId))
{
int pos = balti.FindIndex(Balta => Balta.cantApa == -1);
balti[pos] = balta;
}
else //daca nu inseamna ca aduaugi balta la lista
{
balti.Add(balta);
}
}
}
And main looks something like this
static void Main(string[] args)
{
Baltile balti = new Baltile();
while (true)
{
"data input block"
for (int i = 0; i < unitCount; i++)
{
"more data input"
if (i>2)
{
Balta balta = new Balta(x, y, radius, extra, unitId, 0);
Baltile.populate(balta);//the CS0120 error is here
}
}
}
}
So CS0120 tells me this An object reference is required for the non-static field, method, or property.This means main is static so i cant call a non static method if i understood right ? Declaring everything static will give even more errors.
How should i go around this ? I cant seem to figure out how to make my code work ?
With
Baltile.populate(balta);
and Baltile being a class name, this would require populate() to be a static method.
As per MSDN, the full error message is
Compiler Error CS0120
An object reference is required for the nonstatic field, method, or
property 'member'
This tells you to use an object instead of a class. And it seems you already have an object called balti that serves this purpose. So use
balti.populate(balta);
instead. Now you call the populate() method on an instance (an object) instead of the class.
EDIT: Updated to include actual code.
I am having an issue with some custom generic interfaces and I am not entirely sure what to do. The error I'm getting is:
Cannot convert from Map to IMap<ICell>
That error pops up when I try to pass Map as a parameter to a method that accepts IMap<ICell>. I have pasted sample code below. Just to be clear, FieldOfView doesn't use anything that hasn't been defined in ICell or IMap.
public class Map : IMap<Cell>
{
private FieldOfView _fieldOfView;
public int Width { get; }
public int Height { get; }
public Map(int width, int height)
{
Width = width;
Height = height;
_fieldOfView = new FieldOfView(this as IMap<ICell>);
_fieldOfView = new FieldOfView((IMap<ICell>)this);
}
public IEnumerable<Cell> GetAllCells()
{
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
yield return GetCell(x, y);
}
}
}
public Cell GetCell(int x, int y)
{
return new Cell(x, y);
}
public void Copy(IMap<Cell> sourceMap)
{
// ...
}
public override string ToString()
{
var sb = new StringBuilder();
foreach (var cell in GetAllCells())
{
sb.Append(cell.ToString());
}
return sb.ToString();
}
}
public interface IMap<T> where T : ICell
{
int Width { get; }
int Height { get; }
IEnumerable<T> GetAllCells();
T GetCell(int x, int y);
void Copy(IMap<T> sourceMap);
}
public class Cell : ICell
{
public int X { get; }
public int Y { get; }
public Cell(int x, int y)
{
X = x;
Y = Y;
}
public override string ToString()
{
return "overloaded";
}
}
public interface ICell
{
int X { get; }
int Y { get; }
}
public class FieldOfView
{
private readonly IMap<ICell> _map;
public FieldOfView(IMap<ICell> map)
{
_map = map;
}
public void DoStuff()
{
foreach (var cell in _map.GetAllCells())
{
// ...
}
}
}
This is similar to this stack overflow question, but a little different. I tried implementing an interface IMap as well as IMap<T> : IMap where T : ICell, but am having issues with that as well.
Lastly, I'm not sure if this is solvable with co/contravariance, but I am using C#3.0 so that is out of the picture for me (unless switching versions is the only way).
I think it would be fine with an implicit / direct cast?
_fieldOfView = new FieldOfView(this as IMap<ICell>); // or
_fieldOfView = new FieldOfView((IMap<ICell>)this);
But if there is a better way, I would like to do that. Resharper does throw me a warning when I cast Map to IMap<ICell> saying:
Suspicious cast: there is no type in the solution which is inherited from both Map and IMap<ICell>.
EDIT2: Look's like neither of the casts worked. I've decided instead to make Map be derived from IMap and just create the Cell objects where needed in the code.
Thanks #Rob and #MK87 for your help!
No, IMap<Cell> is not the same as IMap<ICell>, so this line:
_fieldOfView = new FieldOfView(this as IMap<ICell>);
will always pass null as parameter.
Yes, this is definitely solvable with variance.
For example, you can have:
IEnumerable<object> list = new List<string>();
since list is IEnumerable<outT>, that means that every IEnumerable<TT> with TT that derives from T is a valid value for list. So the List doesn't have to be of object, it can be of any derived type.
But because you can't use variance, we need another hack.
Possible solution: instead of deriving Map from IMap<Cell>, derive it from IMap<ICell>. You'll have only to correct some points, for example the return type of GetCell() must become ICell instead of Cell. Is it feasable for you?
I would like to create a method that uses the keyword in instead of a comma to separate parameters in a method declaration; something similar to the foreach(a in b) method.
Example
Class Structure
public class Length
{
public double Inches;
public double Feet;
public double Yards;
public enum Unit { Inch, Foot, Yard }
Dictionary<Unit, double> inchFactor = new Dictionary<Unit, double>()
{
{ Unit.Inch, 1 },
{ Unit.Foot, 12 },
{ Unit.Yard, 36 }
};
public Length(double value, Unit unit)
{
this.Inches = value * inchFactor[unit];
this.Feet = this.Inches / inchFactor[Unit.Foot];
this.Yards = this.Inches / inchFactor[Unit.Yard];
}
}
Method Definition in Class
// I'd like to know how to use "in" like this ↓
public List<Length> MultiplesOf(Length divisor in Length dividend)
{
double inchEnumeration = divisor.Inches;
List<Length> multiples = new List<Length>();
while (inchEnumeration <= dividend.Inches)
{
multiples.Add(new Length(inchEnumeration, Length.Unit.Inch));
inchEnumeration += divisor.Inches;
}
return multiples;
}
Ideal Implementation
private void DrawRuler()
{
Length eighthInch = new Length(0.125, Length.Unit.Inch);
Length oneFoot = new Length(1, Length.Unit.Foot);
// Awesome.
List<Length> tickGroup = Length.MultiplesOf(eighthInch in oneFoot);
double inchPixels = 10;
foreach (Length tick in tickGroup)
{
// Draw ruler.
}
}
I've looked into creating new keywords, but it looks like C# does not support defining keywords.
As has been mentioned in the comments, you cannot define custom keywords in C# (unless you extend the compiler, which is an advanced task). However, if your goal is to clarify the meaning of the two arguments, then I would suggest using named arguments instead:
// Define the method as usual:
public List<Length> MultiplesOf(Length divisor, Length dividend)
{
// ...
}
// Then call it like so, explicitly showing what is the divisor and the dividend:
List<Length> tickGroup = Length.MultiplesOf(divisor: eighthInch, dividend: oneFoot);
While you can't redefine an existing keyword, there is other way to accomplish what you in a slightly different way using Fluent Interface :
public class Length
{
// ...
public static IFluentSyntaxProvider MultiplesOf(Length divisor)
{
return new FluentSyntaxProvider(divisor);
}
public interface IFluentSyntaxProvider
{
List<Length> In(Length dividend);
}
private class FluentSyntaxProvider : IFluentSyntaxProvider
{
private Length divisor;
public FluentSyntaxProvider(Length divisor)
{
this.divisor = divisor;
}
public List<Length> In(Length dividend)
{
double inchEnumeration = divisor.Inches;
List<Length> multiples = new List<Length>();
while (inchEnumeration <= dividend.Inches)
{
multiples.Add(new Length(inchEnumeration, Length.Unit.Inch));
inchEnumeration += divisor.Inches;
}
return multiples;
}
}
}
Example of usage :
// Awesome.
List<Length> tickGroup = Length.MultiplesOf(eighthInch).In(oneFoot);
I have a following problem:
I have interface ILocation, which includes functions to get position of feature (in 2D grid). Not all classes can have this interface, but those, which do, are not related to each other (do not inherit from each other etc.). I.e. classes with this interface are Person, Item, BuildingBlock...
Now I have class Location, which includes variable "block". Basically anything can be there, with one condition: it must implement interface ILocation. How can I do that? I do not know, which class will be in this variable, and therefore have to specify it as an Object, but I know, it must implement ILocation. How can this be done?
In following example, I want to implement method Symbol, which is in ILocation interface.
public class Location :ILocation
{
public int X {get; set;}
public int Y {get; set;}
public Object block;
public Location (int x, int y, Object o)
{
X = x;
Y = y;
block = o;
}
public char Symbol()
{
return block.Symbol();
}
}
And this of course produces an Error, since instance block of class Object does not implement ILocation.
So - how can I tell C#, that in variable "block" can be any object, which implements ILocation?
Thanks
Zbynek
Declare block variable as location:
public ILocation block;
public Location (int x, int y, ILocation o)
{
X = x;
Y = y;
block = o;
}
Either what lazyberezovsky said or, if you also need to keep knowledge of the exact type of block, you can use something with generics like:
public class Location<TBlock> : ILocation
where TBlock : ILocation
{
public int X { get; set; }
public int Y { get; set; }
public TBlock block;
public Location(int x, int y, TBlock o)
{
X = x;
Y = y;
block = o;
}
public char Symbol()
{
return block.Symbol();
}
}
Replace Object with ILocation.
public ILocation block;
public Location (int x, int y, ILocation o)
So whenever you make object of Location you can pass any object which implements ILocation interface.
var book = new Book(); // Book implements ILocation.
var person = new Person(); // Person implements ILocation.
var table = new Table(); // Table doesn't implement ILocation.
var bookLocation = new Location(1, 2, book);
var personLocation = new Location(2, 3, person);
var tableLocation = new Location(2, 3, table); // Compile error as table doesn't implement ILocation,