Unable to Modify struct Members - c#

I'm not at all new to programming, but there seems to be a hole in my understanding of C# structs.
Can anyone explain why the following code prints out the following?
Dist1: 0, Dist2: 0
struct Distance
{
public void SetFeet(int feet) { Value = feet; }
public void SetMiles(float miles) { Value = (int)(miles * 5280f); }
public int GetFeet() { return Value; }
public float GetMiles() { return Value / 5280f; }
private int Value;
}
class Distances
{
public Distance Dist1 { get; set; }
public Distance Dist2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
Distances distances = new Distances();
distances.Dist1.SetFeet(1000);
distances.Dist2.SetFeet(2000);
Console.WriteLine("Dist1: {0}, Dist2: {1}",
distances.Dist1.GetMiles(),
distances.Dist2.GetMiles());
Console.ReadLine();
}
}

Getters and setters -- how properties are accessed -- still function like methods in this regard. That is,
distances.Dist1.SetFeet(1000);
is "equivalent" to
distances.GetDist1().SetFeet(1000);
The "copy" of the structure (value) is made when it is returned from the getter (or passed to the setter). If Dist1 were a member variable this would not be the case and would work "as expected".
Happy coding.

struct are value types - so when you are accessing distances.Dist1.SetFeet you basically are accessing a copy... see for example at MSDN http://msdn.microsoft.com/en-us/library/aa288471%28v=vs.71%29.aspx
[EDIT after comment]
On the other hand, if you do distances.Dist1 = new Distance ().SetFeet (1000); AND change the return of SetFeet from void to Distance it should work. Alternatively make Distance a class.
For a reference on how to build structs in a way that they work as expected see the DateTime struct in the framework - http://msdn.microsoft.com/en-us/library/system.datetime.aspx
[/EDIT after comment]

Properties are treated differently to variables, just remove { get; set; } from your Distance declaration and the code works fine.
struct Distance
{
public void SetFeet(int feet) { Value = feet; }
public void SetMiles(float miles) { Value = (int)(miles * 5280f); }
public int GetFeet() { return Value; }
public float GetMiles() { return Value / 5280f; }
private int Value;
}
class Distances
{
public Distance Dist1;//here
public Distance Dist2;//and here
}
class Program
{
static void Main(string[] args)
{
Distances distances = new Distances();
distances.Dist1.SetFeet(1000);
distances.Dist2.SetFeet(2000);
Console.WriteLine("Dist1: {0}, Dist2: {1}", distances.Dist1.GetMiles(),
distances.Dist2.GetMiles());
Console.ReadLine();
}
}

Related

Make struct pointing to different struct in C# [closed]

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 6 months ago.
Improve this question
class IntComponent
{
public int size;
}
class IntReferenceComponent : IntComponent
{
public IntComponent target; // keep my size same as target size
private void OnValidate()
{
//triggered on target assignment
}
}
Is it possible in C# make struct variable pointing to different struct variable like with objects ? Even with unsafe pointers ?
Edit
The final solution according to Charlieface solution:
public abstract class StructComponent<T> where T : struct
{
public T size;
}
public class IntComponent : StructComponent<int>{ }
public class IntReferenceComponent : IntComponent
{
public IntComponent target;
public new int size
{
get => target.size;
set => target.size = value;
}
}
In Unity I had to create custom editor:
public abstract class StructComponentEditor<T, D> : Editor where T : struct where D : StructComponent<T>
{
public static object StructField(string label, T value, params GUILayoutOption[] options)
{
switch (value)
{
case Vector3 v:
return EditorGUILayout.Vector3Field(label, v, options);
case Vector2 v:
return EditorGUILayout.Vector2Field(label, v, options);
case float f:
return EditorGUILayout.FloatField(label, f, options);
case int i:
return EditorGUILayout.IntField(label, i, options);
case double d:
return EditorGUILayout.DoubleField(label, d, options);
case Color c:
return EditorGUILayout.ColorField(label, c, options);
}
return null;
}
public void DrawDefaultStructComponent()
{
D target = serializedObject.targetObject as D;
PropertyInfo sizeProp = target.GetType().GetProperty("size");
object value;
try
{
value = sizeProp.GetValue(target);
}
catch
{
value = new T();
}
if(sizeProp.SetMethod != null)
{
sizeProp.SetValue(target, StructField("Size", (T)value));
return;
}
StructField("Size", (T)value);
}
public override void OnInspectorGUI()
{
DrawDefaultStructComponent();
DrawDefaultInspector();
}
}
[CustomEditor(typeof(StructComponent<int>), true)]
[CanEditMultipleObjects]
public class IntComponentEditor : StructComponentEditor<int, StructComponent<int>> { }
I need to write something because most of it is just code :)))))) So thanks to everyone who helped :) I love you <3
You don't need to do this in your case, and generally it would be ill-advised to try and mess around with pointers in normal Object Oriented cases, as you don't normally expose the internals of a class.
Instead, just use composition, with an outer property exposing the value of the inner object
class IntReferenceComponent : IntComponent
{
public IntComponent target; // keep my size same as target size
public int Size
{
get => target.size;
set => target.size = value;
}
}
You Can not do this with struct since its value type means you only can take a copy from it and you can't use it as a pointer as you do with classes
Below Code shows that even with pointers unsafe code will not work because you, in the end, will copy the values to a struct to use them,
since you can't access the object attribute with the pointer that
just `point to the object itself (this is what I know )
namespace Feto
{
internal struct Complex
{
public float real;
public float imag;
public Complex(float real, float image)
{
this.real = real;
this.imag = image;
}
public override string ToString()
{
return $" Class Complex {this.real} , {this.imag}";
}
}
class FixingComplex
{
public float real;
public float imag;
public FixingComplex(float real, float image)
{
this.real = real;
this.imag = image;
}
public override string ToString()
{
return $" Class Complex {this.real} , {this.imag}";
}
}
unsafe class program
{
public static void Main()
{
Complex x = new Complex(10, 20);
Console.WriteLine(x);
Complex* y = &x;
//address of stuct
Console.WriteLine((int)&x);
//the y point to it
Console.WriteLine((int)y);
//what z point to
Console.WriteLine(*y);
//send the addresss of the stuct
addNumbers(y);
Console.WriteLine(x);
Console.ReadKey();
void addNumbers(Complex* result)
{
//make sure it is the same address of stuct
Console.WriteLine((int)result);
//now here we got the address of struct we need to modify it
Console.WriteLine(*result);
//Here is the problem it will take copy
var value = *result;
value.real = 8888;
value.imag = 8888;
//you can use fixedcomplex to go on with pointers and workaround
.....
}
}
}
}
But there is a Solution
with small modifications like passing the address as a reference, not a copy of the address this will workaround and change the values and
The Changes addNumbers(ref y); void addNumbers(ref Complex* result) *result = new Complex(8888,8888);
namespace Feto
{
internal struct Complex
{
public float real;
public float imag;
public Complex(float real, float image)
{
this.real = real;
this.imag = image;
}
public override string ToString()
{
return $" Class Complex {this.real} , {this.imag}";
}
}
class FixingComplex
{
public float real;
public float imag;
public FixingComplex(float real, float image)
{
this.real = real;
this.imag = image;
}
public override string ToString()
{
return $" Class Complex {this.real} , {this.imag}";
}
}
unsafe class program
{
public static void Main()
{
Complex x = new Complex(10, 20);
Console.WriteLine(x);
Complex* y = &x;
//address of stuct
Console.WriteLine((int)&x);
//the y point to it
Console.WriteLine((int)y);
//what z point to
Console.WriteLine(*y);
//send the addresss of the stuct
addNumbers(ref y);
Console.WriteLine(x);
Console.ReadKey();
void addNumbers(ref Complex* result)
{
//make sure it is the same address of stuct
Console.WriteLine((int)result);
//now here we got the address of struct we need to modify it
Console.WriteLine(*result);
//Here is the problem it will take copy
//var value = *result;
*result = new Complex(8888,8888);
//you can use fixedcomplex to go on with pointers and workaround
}
}
}
}

Unity/C# one function to set any int?

I've got a small project where I would like to avoid creating a setter for each integer.
So I'm thinking if it's even possible.
So I would like to set an amount of
player.setResource(player.money, 100);,
player.setResource(player.coal, 20);,
etc.
I'm not sure first of all if it's possible, and second of all how to write a function itself.
public void setResource(int resource, int amount)
{
???
}
Use an enum for this. Define an enum in your project like so
public enum ResourceType { Coal = 0, Money = 1, Health = 2 }
Now, you can add a switch case in your setResource function to check what enum you've passed, and set the corresponding value. This is however assuming all your values are integers. you can make a separate one for floats, or just use floats for everything, upto you.
This will be your new SetResource Function, assuming you have a reference to your player.
public void setResource(ResourceType resource, int amount)
{
switch(resource)
{
case ResourceType.Money:
player.money = amount;
break;
case ResourceType.Coal:
player.coal = amount;
break;
}
}
You can use an Enum to define the resources types and a Dictionary to store the values of each resource. Here's an example:
public enum ResourceType
{
Coal,
Money
}
private Dictionary<ResourceType, int> _resources = new Dictionary<ResourceType, int>();
public void SetResource(ResourceType resourceType, int value)
{
_resources[resourceType] = value;
}
public int GetResource(ResourceType resourceType, int defaultValue = 0)
{
if (_resources.TryGetValue(resourceType, out var value))
return value;
else
return defaultValue;
}
public class Player
{
public int money { get; set; }
public int coal { get; set; }
public void setResource(string resource, int amount)
{
this.GetType().GetProperty(resource).SetValue(this, amount);
}
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Player player = new Player();
player.setResource(nameof(player.coal), 4);
}
}
In your method, the target is not passed, the value of the integer is assigned to a local variable resource that only exists within the method.money and coal are not affected.
You need to pass the address of those data.
public void setResource(ref int resource, int amout)
{
resource = amount;
}
player.setResource(ref player.coal, 100);
If nothing else happens in the method, a get/set property would do the same.
There are multiple ways how you could do this.
I often use this aproach for quick prototyping.
First you create two variables for the data you want to assing, then you create a Setter function and with this you can set variables through other scripts.
int value 1;
int value 2;
public void SetData(int value1, int value2)
{
this.value1 = value1;
this.value2 = value2;
}
The same aproach can be used for other data types, you just need to create the variables.

C# How to set non-user-inputted variable values/instances for an object (multiple classes)

I'm working on a simple practice program and it works as it's supposed to. However, it led me to realize that I'm fuzzy on an important area which I want to understand more thoroughly. I created an object (or instance?) aPay. The program asks the user to enter values for three variables (in the Main(Program) class). Those values/instances are assigned to aPay. aPay.WorkerName, aPay.HoursWorked, and aPay.RateOfPay. I have a number of constants and variables with calculated values which are instantiated/calculated in the Pay class. These are non-user-inputted values. I want to send the values of each of those to the object aPay, similar to what was done with the user-inputted values. I know it's not neccessary in this program, however it's useful in more complex programs and I'd like to understand how to achieve this. I do not want to output anything more or alter the functioning of the program, I simply want to assign the values of the variables (GrossPay, NetPay, FicaTax, FedTax, StateTax, and HealthIns) to the aPay object. (I'm not sure if I'd use the variables (grossPay, netPay, fedTax, ficaTax, etc instead of the properties I just listed).
I know I could do this by doing Pay aPay = new Pay(workerName, hoursWorked, rateOfPay, grossPay, netPay, fedTax, ficaTax, stateTax, healthIns)
or something similar to this?
aPay = { workerName, hoursWorked, rateOfPay, grossPay, etc } ????
Can someone please explain how I could go about achieving this and provide example code using my code specifically? I will list the code below:
class MainClass
{
public static void Main(string[] args)
{
Header();
Directions();
Pay aPay = new Pay();
Write("**********************************\n");
Write("Enter name: ");
aPay.WorkerName = ReadLine();
Write("Enter hours: ");
aPay.HoursWorked = double.Parse(ReadLine());
Write("Enter rate: ");
aPay.RateOfPay = double.Parse(ReadLine());
Write("**********************************\n");
//
//
//
//
//
WriteLine(aPay.ToString());
ReadLine();
}
private static void Header()
{
WriteLine("*************************************************************");
WriteLine("\t Pay");
WriteLine("\t Calculate Net Pay");
WriteLine("\t Matt Craig");
WriteLine("\t " + DateTime.Today);
WriteLine("*************************************************************");
}
private static void Directions()
{
WriteLine("This program will determine pay.");
WriteLine(" ");
WriteLine("You will be asked to enter hours worked"
+ "\n and rate of pay.");
WriteLine(" ");
WriteLine("*************************************************************");
}
}
~~~~~~~~~~~~~~~~~~~~~~Pay Class Below~~~~~~~~~~~~~~~~~~~~~
public class Pay
{
private string workerName;
private double hoursWorked;
private double rateOfPay;
private double grossPay;
private double netPay;
private double FICA_TAX = 0.0765;
private double FED_TAX = 0.20;
private double STATE_TAX = 0.10;
private double HEALTH_INS = 0.07;
private double ficaTax;
private double fedTax;
private double stateTax;
private double healthIns;
public Pay()
{
}
public string WorkerName
{
set
{
workerName = value;
}
}
public double HoursWorked
{
set
{
hoursWorked = value;
}
}
public double RateOfPay
{
set
{
rateOfPay = value;
}
}
private double GrossPay
{
get
{
grossPay = Math.Round((hoursWorked * rateOfPay), 2, MidpointRounding.AwayFromZero);
return grossPay;
}
}
private double NetPay
{
get
{
netPay = Math.Round((grossPay - ficaTax - fedTax - stateTax - healthIns), 2, MidpointRounding.AwayFromZero);
return netPay;
}
}
private double FicaTax
{
get
{
ficaTax = Math.Round((FICA_TAX * grossPay), 2, MidpointRounding.AwayFromZero);
return ficaTax;
}
}
private double FedTax
{
get
{
fedTax = Math.Round((FED_TAX * grossPay), 2, MidpointRounding.AwayFromZero);
return fedTax;
}
}
private double StateTax
{
get
{
stateTax = Math.Round((STATE_TAX * grossPay), 2, MidpointRounding.AwayFromZero);
return stateTax;
}
}
private double HealthIns
{
get
{
healthIns = Math.Round((HEALTH_INS * grossPay), 2, MidpointRounding.AwayFromZero);
return healthIns;
}
}
public override string ToString()
{
string stats;
stats = string.Format("Name\t\t {0} \n", workerName);
stats += string.Format("Gross Pay\t {0:c} \n", GrossPay);
stats += string.Format("FICA tax\t {0:c} \n", FicaTax);
stats += string.Format("Federal tax\t {0:c} \n", FedTax);
stats += string.Format("State tax\t {0:c} \n", StateTax);
stats += string.Format("Health Insurance {0:c} \n", HealthIns);
stats += string.Format("Net pay\t\t {0:c} \n", NetPay);
return stats;
}
}
I believe what you're trying to describe is implemented using constructors. Let's look at the code you have. You have a class Pay with a set of properties. For simplification I'm going to assume there are just three of them: WorkerName, HoursWorked, RateOfPay to start with.
Let's start with a class that describes these properties:
public class Pay
{
public string WorkerName { get; set; }
public double HoursWorked { get; set; }
public double RateOfPay { get; set; }
}
There is a number of things I'd deem as "wrong" with the class definition above, but let's tackle one problem at a time.
First, we need to calculate health insurance cost. It depends on health insurance multiplier (0.7), which in our case is a static value. Let's add it to a class:
public class Pay
{
private static double HEALTH_INS = 0.07;
public string WorkerName { get; set; }
public double HoursWorked { get; set; }
public double RateOfPay { get; set; }
private double HealthIns
{
get
{
return Math.Round((HEALTH_INS * HoursWorked * RateOfPay), 2, MidpointRounding.AwayFromZero);
}
}
// With latest versions of C# you could actually do this:
private double HealthInsAlt => Math.Round((HEALTH_INS * grossPay), 2, MidpointRounding.AwayFromZero);
}
Now, let's talk about your scenario: you'd like to assign these values. First of all, if the value is relevant and is used just within the class (Pay in this case) - doing what I've described above is totally fine and I personally prefer it this way - it's easy to read the code and understand where the value is coming from.
But sometimes (more complicated scenarios) it just does not work. Let's introduce a business case like this: the Health Insurance multiplier is now dynamic, depends on the rate of pay and is coming from a database. For simplification purposes, I'm going to assume that we can get it by using some kind of repository: InsuranceMultipliersRepository.GetHealthMultiplier(RateOfPay).
We can retrieve the value in the constructor which is called when a new instance of an object with the specified class is created. Let's implement it:
public class Pay
{
private static double HEALTH_INS { get; }
public string WorkerName { get; set; }
public double HoursWorked { get; set; }
public double RateOfPay { get; set; }
private double HealthIns
{
get
{
return Math.Round((HEALTH_INS * HoursWorked * RateOfPay), 2, MidpointRounding.AwayFromZero);
}
}
public Pay() {
// This is a parameterless constructor. C# compiler actually generates this for you behind the scenes and sets every value to the default for its type. We're basically saying "use this instead of default one when creating an object" and providing additional instructions. In our case, the instruction would be retrieving the multiplier from the repository and storing it within the Pay class property.
var insuranceRepo = new InsuranceMultipliersRepository();
this.HEALTH_INS = insuranceRepo.GetHealthMultiplier(RateOfPay);
}
}
Now, there's a serious flaw there: we do not have the RateOfPay set yet! Which means that we need to modify the constructor to ensure that the RateOfPay value is known when we're creating a new instance of the Pay object. Let's do it:
public class Pay
{
private static double HEALTH_INS { get; }
public string WorkerName { get; set; }
public double HoursWorked { get; set; }
public double RateOfPay { get; set; }
private double HealthIns
{
get
{
return Math.Round((HEALTH_INS * HoursWorked * RateOfPay), 2, MidpointRounding.AwayFromZero);
}
}
public Pay(double rateOfPay) {
var insuranceRepo = new InsuranceMultipliersRepository();
this.RateOfPay = rateOfPay;
this.HEALTH_INS = insuranceRepo.GetHealthMultiplier(rateOfPay);
}
}
Ok, looks better now. But by changing the constructor to be parameterized, we've effectively made the following code invalid: var somePay = new Pay();. C# compiler will not generate default parameterless constructors for class implementations (it will still do so in some scenarios, for abstract classes for example).
Couple of things worth mentioning: you can see that there is no set method for HEALTH_INS but we are still setting the value. How? The reality is that we are allowed to set readonly properties or properties without a setter in a constructor (with C#6+). If you are using C#5 or earlier versions you will have to create a backing property (for public properties, if you have a private one it's safe to simply leave the setter there, noone can see it anyway), something like this if we need to make our insurance multiplier public and readable:
public class Pay
{
private static double _HEALTH_INS { get; set; }
public double HEALTH_INS { get { return _HEALTH_INS; } }
public string WorkerName { get; set; }
public double HoursWorked { get; set; }
public double RateOfPay { get; set; }
private double HealthIns
{
get
{
return Math.Round((HEALTH_INS * HoursWorked * RateOfPay), 2, MidpointRounding.AwayFromZero);
}
}
public Pay(double rateOfPay) {
var insuranceRepo = new InsuranceMultipliersRepository();
this.RateOfPay = rateOfPay;
this._HEALTH_INS = insuranceRepo.GetHealthMultiplier(rateOfPay);
}
}
Another thing I've noticed about your code: your public properties have setters. This effectively makes your class mutable. It means that you can never be sure that the value of the property has not been changed/is correct. Imagine a scenario: you create an instance of Pay object and set the RateOfPay. You pass this object to methods, use it in different places. Then, by mistake, you or other developer write kind of code:
public void AdjustPayForHours (Pay payToAdjust)
{
// If someone worked for less than half an hour their rate of pay should be reduced in half
if (payToAdjust.HoursWorked < 0.5) {
payToAdjust.RateOfPay = payToAdjust.RateOfPay * 5.0
}
}
Now, you see what's going on. It should be payToAdjust.RateOfPay * 0.5 but there is a typo which can significantly affect other pieces of the application/business. It is possible because your class is mutable. My personal opinion regarding the types, interfaces and other objects defining the domain model: no class property (update 03/20/2017 added the missed word) should have public setters1. All properties should be set in a constructor. If mutability is required properties should be changed via methods. If mutability is not required - properties should be readonly and setters should either not exist or be private2. Preferably, all properties should be private and values should be retrieved using methods as well. Again, this is my personal opinion, it may be wrong, sub-optimal, but that's what I believe in. It's, for sure, the safest way. Here's an example (C#7 based, for C#5 and earlier you will need a separate backing property for each public property):
public class Worker
{
// Here the property is public, so you'd be able to do the following:
// var contractor = new Worker("John");
// string contractorName = contractor.WorkerName;
public string WorkerName { get; }
public Worker(string workerName)
{
this.WorkerName = workerName;
}
}
public class Pay
{
private static double HEALTH_INS { get; }
// Three properties below are private and are set in the constructor.
// The "HoursWorked" has a setter because sometimes we need to add hours.
// Others don't because we set them once when we create an object
// You're NOT able to do:
// var someWorkersPay = new Worker();
// var someWorkersRate = someWorkersPay.RateOfPay;
private string WorkerName { get; }
private double HoursWorked { get; set; }
private double RateOfPay { get; }
public double GrossPay { get { return HoursWorked * RateOfPay; } }
private double HealthIns
{
get
{
return Math.Round((HEALTH_INS * HoursWorked * RateOfPay), 2, MidpointRounding.AwayFromZero);
}
}
public Pay(Worker workerWithPay, double hoursSpent, double payRate) {
var insuranceRepo = new InsuranceMultipliersRepository();
this.WorkerName = workerWithPay.WorkerName;
this.HoursWorked = hoursSpent;
this.RateOfPay = payRate;
this._HEALTH_INS = insuranceRepo.GetHealthMultiplier(rateOfPay);
}
public void AddHoursWorked(double hoursToAdd) {
this.HoursWorked += hoursToAdd;
}
public double GetRateOfPay() {
return this.RateOfPay;
}
// Now you can do someWorkersPay.GetRateOfPay();
}
Update 03/20/17: Implementation above does not make the object deeply immutable, but can be classified as shallow immutability.
Finally, you've asked about larger applications. In a larger codebase, developers use different patterns. For my scenario (insurance multiplier in the database) two would be most useful: Inversion of control and Dependency Injection.
There are a lot of articles and docs online on these two patterns, so I won't go into the details. Just a simple explanation: using these allows developers to avoid thinking about the location of the health insurance rates, how the should get it (inversion of control) and also allows to avoid creating new instances of repositories (or other dependencies) when we need to instantiate a new object. In my example InsuranceMultipliersRepository is a dependency of Pay - we need it to create a new Pay. Dependency injection allows us to do something like this:
public class Pay
{
private static readonly IHealthInsuranceRepository _insuranceRepo { get; }
public string WorkerName { get; set; }
public double HoursWorked { get; set; }
public double RateOfPay { get; set; }
private double HealthMultiplier { get { return _insuranceRepo.GetHealthMultiplier(RateOfPay); } }
private double HealthIns
{
get
{
return Math.Round((HealthMultiplier * HoursWorked * RateOfPay), 2, MidpointRounding.AwayFromZero);
}
}
public Pay(double rateOfPay, IHealthInsuranceRepository healthInsuranceRepository) {
_insuranceRepo = healthInsuranceRepository;
this.RateOfPay = rateOfPay;
}
}
Note: my code is just an example, it's recommended to separate concerns further with different layers (repository, service, application logic, domain, etc.).
1: Property Design Guidelines
2: Field Design Guidelines

Vector math dimension consistency check at compile-time

I am creating a linear algebra library in C#, and I would like to force dimension inconsistency errors up to compile-time. I've implemented a similar solution to this, where the trait I use is a class that uniquely maps to an integer. The problem is for every possible size I would like my Vectors to have, I would need to create a class with a unique name to represent it.
Here is an example of that implementation:
public class Vector<T> where T: ISize, new()
{
static readonly T size = new T();
List<double> values;
public Vector(List<double> values)
{
if (values.Count != size.Size)
throw new IndexOutOfRangeException();
this.values = new List<double>(values);
}
public double Get(int index)
{
return values[index];
}
public Vector<T> Add(Vector<T> other)
{
var vv = new List<double>();
for (int ii = 0; ii < size.Size; ++ii)
vv.Add(other.Get(ii) + this.values[ii]);
return new Vector<T>(vv);
}
}
public interface ISize
{
int Size { get; }
}
public class S1 : ISize
{
public int Size
{
get { return 1; }
}
}
public class S2 : ISize
{
public int Size
{
get { return 2; }
}
}
And here's an example of its usage:
class Program
{
static void Main(string[] args)
{
var v1 = new Vector<S2>(new List<double>() { 1, 2 });
var v2 = new Vector<S2>(new List<double>() { 10, -4 });
var z1 = new Vector<S1>(new List<double>() { 10 });
// works
var v3 = v1.Add(v2);
// complie-time error
var z2 = z1.Add(v1);
}
}
This works quite well for my purposes, except for the fact that I would need to create a different implementation of ISize for every possible Vector size. Is there any way for me to implement the Vector class that would allow me to get around this problem?
In order to get a compile-time error, you need to have different types. C# does not have a concept that let's you define a type parameter that itself takes a kind of value parameters - which is what you would need to do this.
Therefore, I don't think what you are asking is possible.
I think there might be a way to make unique types for family of vector instances using anonymous types, but that's going to be quirky and I don't think it would provide the type safety that you want.
C++ has such a concept in templates (so it's not unreasonable), just not possible in C#.
You can create a single N-dimentional Vector class with compile time type checking, but it's pretty messy. What we're creating here is LISP style linked-lists, but through generic type arguments rather than purely out of object references via fields.
public interface IVector
{
double Value { get; }
IVector Tail { get; }
}
public class Vector<T> : IVector
where T : IVector
{
internal Vector(double value, T tail)
{
Value = value;
Tail = tail;
}
public double Value { get; private set; }
public T Tail { get; private set; }
public Vector<Vector<T>> Add(double value)
{
return new Vector<Vector<T>>(value, this);
}
}
internal class EmptyVector : IVector
{
public double Value
{
get { throw new NotImplementedException(); }
}
public IVector Tail
{
get { return null; }
}
}
public static class Vector
{
public static readonly Vector<IVector> Empty = new Vector<IVector>(
0, new EmptyVector());
public static IEnumerable<double> AllValues(this IVector vector)
{
IVector current = vector;
while (current != Vector.Empty && current != null)
{
yield return current.Value;
current = current.Tail;
};
}
}
This allows us to write:
var v1 = Vector.Empty.Add(1).Add(2);
var v2 = Vector.Empty.Add(10).Add(-4);
var z1 = Vector.Empty.Add(10);
v1 = v2;//works, as they are the same type
z1 = v2;//fails, as they aren't the same type, since they're a different size
This allows allows you to write a method that accepts a vector of a particular size. It's not convenient, and it doesn't scale, but it works. If you want, say, a 3D vector as a parameter, you can write:
public static void Foo(Vector<Vector<Vector<IVector>>> vector)
{
var first = vector.Value;
var second = vector.Tail.Value;
var third = vector.Tail.Tail.Value;
}

C# Errors and Headache >.< (MonoDevelop version2.8.2 for Unity 3d)

Ok so I have a problem :/ first off Im using C#.. Next, in the section where you see
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
I get 3 Errors
1) Unexpected symbol `{'
2)Unexpected symbol `{' in class, struct, or interface member declaration
and
3) Parsing Error
and frankly its pissing me off -_- so does anyone know what the problem may be?
public class BaseStats {
private int _basevalue; //base value of this stat
private int _buffvalue; //amount needed to buff the stat
private int _expToLevel; //amount needed to move to the next level
private float _LevelModifier; //the modifier applied to the exp needed to raise the skill
public BaseStats()
{
_basevalue = 0;
_buffvalue = 0;
_expToLevel = 100;
_LevelModifier = 1.1f;
}
//Basic Setters and Getters
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
public int BuffValue()
{
get{return _buffvalue; }
set{_buffvalue value; }
}
public int ExpToLevel()
{
get{return _expToLevel; }
set{_expToLevel.value; }
}
public float LevelModifier()
{
get{return _levelModifier; }
set{_levelModifier.value; }
}
private int CalculateExpToLevel()
{
return (int)(_expToLevel * _levelModifier);
}
public void LevelUp()
{
_expToLevel = CalculateExpToLevel();
_baseValue++;
}
public int AdjustedValue()
{
return _baseValue + _buffValue;
}
}
Properties do not have parentheses. Eliminate the () and fix your setter on what you intend to be properties. Eliminate the get/set on what you intend to be methods.
// this is a property
public int Foo
{
get { return foo; }
set { foo = value; }
}
// this is a method
public decimal Bar()
{
// do something and return a decimal
}
And note, as of C# 3, if your property is a simple get/set operation, you can use auto-implemented properties and eliminate the explicit backing variable.
public int Foo { get; set; }

Categories