The following code will not compile if I include f1().
However, I see both X & Y in intellisense with their values at the call to calculationXY() in the call from f2().
The f1() compile error is: object does not contain a definition or x {or for y for that matter and the .x is red underlined.
private object calculateXY(int id) {
// bla bla bla
return (new { x = calX, y = calY });
}
/*
f1() {
var p = calculateXY(10);
p.x + 1;
}
*/
f2() {
var p = calculateXY(10);
//p.x + 1;
}
I'm added this just to complete the answer.
In the whole solution this class is only instantiated twice. And it is small so I think I'm okay.
public class plotPoint {
public plotPoint (int x, int y){
this.x = x;
this.y = y;
}
public int x { get; set; }
public int y { get; set; }
}
and
private plotPoint calculateXY(int id) {
//bla bla bla
return (new plotPoint(_pointX, _pointY));
}
Although I don't exactly love the name.
I guess I've been doing to much javascript lately. JS would have a problem with what I was hoping to get away with. Oh well.
And so we see the death of yet another pointlessly crazy use of a global variable.
Thanks for everyone's input.
calculateXY returns an object .. which has no x or y properties; you
can return a dynamic instead, or use reflection to read x and y –
KMoussa
and
As #KMoussa states, you're returning an object. Best bet is to return
dynamic, but if you're returning an object, you should just return a
proper class or struct. – TyCobb
Thanks guys.
I'd recommend writing an IntPoint class:
public class IntPoint { int X; int Y; }
And return that. Make sure you declare the method's return type as IntPoint as well, so you can easily use the return value without any nonsense:
private IntPoint CalculateXY(int id) {
// bla bla bla
return new IntPoint { X = calX, Y = calY };
}
...
IntPoint ip = CalculateXY(12);
Console.WriteLine(ip.X);
I would not advise using dynamic for this. If you do it the way I suggest above, that puts the compiler in your corner, working on your behalf to make sure that any code that calls your method knows what it's getting and uses it properly. dynamic is meant for other things, usually fairly exotic things -- I've known about it for years and never yet used it in production code.
Anonymous types, like in your original example, are virtually never returned from methods. That's exotic stuff too, for reasons you discovered already. It's a little more hassle to find a suitable return type sometimes (or write one, as we did above), but it's generally worth the effort.
UPDATE
Here's another option:
private void CalculateXY(int id, out int x, out int y) {
// bla bla bla
x = calX;
y = calY;
}
Call like...
int x, y;
CalculateXY(32, out int x, out int y);
It's not my absolute favorite, but it's an option that's strongly typed, properly named, and doesn't require writing a new class just to hold a return type. I wouldn't mind seeing that in code.
In comments, #KMoussa suggested Tuple<int,int> for a return type. That's feasible, and if it's a private helper function it's not the worst thing you can do, but if the code is being maintained the "Item2 who?" cost over time will exceed the up-front cost of writing a quickie class. Tuple was, IIRC, originally designed to do what anonymous types are now used for.
Related
The code looks like this.
public class One<T> where T : Two {
public static int Y;
static One() {
// Y is to be initialised with the Z value from T
// this code does not compile
// Y = T.Z;
}
public int X { get { return Y; } }
}
public class Two {
public static int Z = 42;
}
public class Three {
public void Main() {
One<Two> a = new One<Two>();
Console.WriteLine("X = {0}", a.X); // should say 42
}
}
The idea is very simple: initialise the static value in a class from another static value in another class passed as a type parameter. There is nothing 'unsafe' about this, but the natural way to do it does not compile (see code).
I've searched SO and found a few near misses, but nothing that hits the spot. I've tried a few things including reflection, but to no avail. Any solution or even hints much appreciated.
Flydog's given you something you could use; I just wanted to make a quick note about my/jimi/enigmativity's comments:
It feel like you're hoping to subclass Two at some point and change out the Z; you reason that if your new class Three, which has a static Z of 43 and derives from Two, is used in combination with One then you'll end up with an .X that is 43. The problem comes in that static things cannot be overridden; they're resolved at compile time and they can look like overriding is at play in certain circumstances, but it's actually overloading or hiding and the compiler is picking something with a particular name in a defined order out of the inheritance tree
Because static things don't inherit (and arguably don't need to because they are hence always known to you, the developer, at compile time) there isn't the expectation that one day someone will subclass your code and write :
One<Four> a = new One<Four>();
And your code will need to pick up whatever they set Z to and use it. You know your Zs and can use them appropriately at compile tine and they know their Zs and should use them appropriately. But I understood where you were going with the T.Z thing..
It almost looks like it should work. Then you start typing T.Z and realize that your gut is agreeing with the compiler. T is a type parameter, it isn't a full fledged type-y thing.
Anyways, this works:
static One()
{
// Y is to be initialised with the Z value from T
var typeT = typeof(T);
var zFieldInfo = typeT.GetField("Z");
Y = (int) zFieldInfo.GetValue(null);
}
Yeah, it uses reflection, but it's only ever going to be run once.
Does the order in which I set properties using the object initializer syntax get executed in the exact same order?
For instance if I do this:
var s = new Person { FirstName = "Micah",
LastName = "Martin",
IsLoaded = true
}
will each property get set in the same order?
Yes.
Apologies for getting interrupted (I have to actually do some work every so often). The spec doesn't explicitly say it, but it makes it pretty clear IMO in section 7.6.10.2:
An object initializer consists of a sequence of member initializers, enclosed by { and } tokens and separated by commas.
(Note the word "sequence" here, rather than "set". I personally think that's significant, as a sequence is ordered.)
The following class represents a point with two coordinates:
public class Point
{
int x, y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
An instance of Point can be created and initialized as follows:
Point a = new Point { X = 0, Y = 1 };
which has the same effect as
Point __a = new Point();
__a.X = 0;
__a.Y = 1;
Point a = __a;
where __a is an otherwise invisible and inaccessible temporary variable.
EDIT: I've had a response from Mads Torgersen, who has basically said that anything which can be done now will preserve the order. There may be some oddities in future where the order is not preserved in weird cases where you're doing something other than setting a property/field, but that will depend on where the language goes.
It's worth pointing out that there are actually lots of steps going on here - there's the order of execution of the evaluation of the arguments (i.e. the RHS bits) and the order of execution of the assignments. For example, if you have:
new Foo
{
A = X,
B = Y
}
all the following orders are possible while still maintaining the order of the actual property execution (A and B):
Evaluate X, assign to A, evaluate Y, assign to B
Evaluate X, evaluate Y, assign to A, assign to B
Evaluate Y, evaluate X, assign to A, assign to B
I believe the first option is the one actually taken, but this was just to demonstrate that there's more to it than meets the eye.
I would also be very wary of actually writing code which depends on this...
Does the order in which I set properties using the object initializer syntax get executed in the exact same order?
For instance if I do this:
var s = new Person { FirstName = "Micah",
LastName = "Martin",
IsLoaded = true
}
will each property get set in the same order?
Yes.
Apologies for getting interrupted (I have to actually do some work every so often). The spec doesn't explicitly say it, but it makes it pretty clear IMO in section 7.6.10.2:
An object initializer consists of a sequence of member initializers, enclosed by { and } tokens and separated by commas.
(Note the word "sequence" here, rather than "set". I personally think that's significant, as a sequence is ordered.)
The following class represents a point with two coordinates:
public class Point
{
int x, y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
An instance of Point can be created and initialized as follows:
Point a = new Point { X = 0, Y = 1 };
which has the same effect as
Point __a = new Point();
__a.X = 0;
__a.Y = 1;
Point a = __a;
where __a is an otherwise invisible and inaccessible temporary variable.
EDIT: I've had a response from Mads Torgersen, who has basically said that anything which can be done now will preserve the order. There may be some oddities in future where the order is not preserved in weird cases where you're doing something other than setting a property/field, but that will depend on where the language goes.
It's worth pointing out that there are actually lots of steps going on here - there's the order of execution of the evaluation of the arguments (i.e. the RHS bits) and the order of execution of the assignments. For example, if you have:
new Foo
{
A = X,
B = Y
}
all the following orders are possible while still maintaining the order of the actual property execution (A and B):
Evaluate X, assign to A, evaluate Y, assign to B
Evaluate X, evaluate Y, assign to A, assign to B
Evaluate Y, evaluate X, assign to A, assign to B
I believe the first option is the one actually taken, but this was just to demonstrate that there's more to it than meets the eye.
I would also be very wary of actually writing code which depends on this...
I'm looking for the C# equivalent of Java's final. Does it exist?
Does C# have anything like the following:
public Foo(final int bar);
In the above example, bar is a read only variable and cannot be changed by Foo(). Is there any way to do this in C#?
For instance, maybe I have a long method that will be working with x, y, and z coordinates of some object (ints). I want to be absolutely certain that the function doesn't alter these values in any way, thereby corrupting the data. Thus, I would like to declare them readonly.
public Foo(int x, int y, int z) {
// do stuff
x++; // oops. This corrupts the data. Can this be caught at compile time?
// do more stuff, assuming x is still the original value.
}
Unfortunately you cannot do this in C#.
The const keyword can only be used for local variables and fields.
The readonly keyword can only be used on fields.
NOTE: The Java language also supports having final parameters to a method. This functionality is non-existent in C#.
from http://www.25hoursaday.com/CsharpVsJava.html
EDIT (2019/08/13):
I'm throwing this in for visibility since this is accepted and highest on the list. It's now kind of possible with in parameters. See the answer below this one for details.
This is now possible in C# version 7.2:
You can use the in keyword in the method signature. MSDN documentation.
The in keyword should be added before specifying a method's argument.
Example, a valid method in C# 7.2:
public long Add(in long x, in long y)
{
return x + y;
}
While the following is not allowed:
public long Add(in long x, in long y)
{
x = 10; // It is not allowed to modify an in-argument.
return x + y;
}
Following error will be shown when trying to modify either x or y since they are marked with in:
Cannot assign to variable 'in long' because it is a readonly variable
Marking an argument with in means:
This method does not modify the value of the argument used as this parameter.
The answer: C# doesn't have the const functionality like C++.
I agree with Bennett Dill.
The const keyword is very useful. In the example, you used an int and people don't get your point. But, why if you parameter is an user huge and complex object that can't be changed inside that function? That's the use of const keyword: parameter can't change inside that method because [whatever reason here] that doesn't matters for that method. Const keyword is very powerful and I really miss it in C#.
Here's a short and sweet answer that will probably get a lot of down votes. I haven't read all of the posts and comments, so please forgive me if this has been previously suggested.
Why not take your parameters and pass them into an object that exposes them as immutable and then use that object in your method?
I realize this is probably a very obvious work around that has already been considered and the OP is trying to avoid doing this by asking this question, but I felt it should be here none-the-less...
Good luck :-)
I'll start with the int portion. int is a value type, and in .Net that means you really are dealing with a copy. It's a really weird design constraint to tell a method "You can have a copy of this value. It's your copy, not mine; I'll never see it again. But you can't change the copy." It's implicit in the method call that copying this value is okay, otherwise we couldn't have safely called the method. If the method needs the original, leave it to the implementer to make a copy to save it. Either give the method the value or do not give the method the value. Don't go all wishy-washy in between.
Let's move on to reference types. Now it gets a little confusing. Do you mean a constant reference, where the reference itself cannot be changed, or a completely locked, unchangeable object? If the former, references in .Net by default are passed by value. That is, you get a copy of the reference. So we have essentially the same situation as for value types. If the implementor will need the original reference they can keep it themselves.
That just leaves us with constant (locked/immutable) object. This might seem okay from a runtime perspective, but how is the compiler to enforce it? Since properties and methods can all have side effects, you'd essentially be limited to read-only field access. Such an object isn't likely to be very interesting.
Create an interface for your class that has only readonly property accessors. Then have your parameter be of that interface rather than the class itself. Example:
public interface IExample
{
int ReadonlyValue { get; }
}
public class Example : IExample
{
public int Value { get; set; }
public int ReadonlyValue { get { return this.Value; } }
}
public void Foo(IExample example)
{
// Now only has access to the get accessors for the properties
}
For structs, create a generic const wrapper.
public struct Const<T>
{
public T Value { get; private set; }
public Const(T value)
{
this.Value = value;
}
}
public Foo(Const<float> X, Const<float> Y, Const<float> Z)
{
// Can only read these values
}
Its worth noting though, that its strange that you want to do what you're asking to do regarding structs, as the writer of the method you should expect to know whats going on in that method. It won't affect the values passed in to modify them within the method, so your only concern is making sure you behave yourself in the method you're writing. There comes a point where vigilance and clean code are the key, over enforcing const and other such rules.
I know this might be little late.
But for people that are still searching other ways for this, there might be another way around this limitation of C# standard.
We could write wrapper class ReadOnly<T> where T : struct.
With implicit conversion to base type T.
But only explicit conversion to wrapper<T> class.
Which will enforce compiler errors if developer tries implicit set to value of ReadOnly<T> type.
As I will demonstrate two possible uses below.
USAGE 1 required caller definition to change. This usage will have only use in testing for correctness of your "TestCalled" functions code. While on release level/builds you shouldn't use it. Since in large scale mathematical operations might overkill in conversions, and make your code slow. I wouldn't use it, but for demonstration purpose only I have posted it.
USAGE 2 which I would suggest, has Debug vs Release use demonstrated in TestCalled2 function. Also there would be no conversion in TestCaller function when using this approach, but it requires a little more of coding of TestCaller2 definitions using compiler conditioning. You can notice compiler errors in debug configuration, while on release configuration all code in TestCalled2 function will compile successfully.
using System;
using System.Collections.Generic;
public class ReadOnly<VT>
where VT : struct
{
private VT value;
public ReadOnly(VT value)
{
this.value = value;
}
public static implicit operator VT(ReadOnly<VT> rvalue)
{
return rvalue.value;
}
public static explicit operator ReadOnly<VT>(VT rvalue)
{
return new ReadOnly<VT>(rvalue);
}
}
public static class TestFunctionArguments
{
static void TestCall()
{
long a = 0;
// CALL USAGE 1.
// explicite cast must exist in call to this function
// and clearly states it will be readonly inside TestCalled function.
TestCalled(a); // invalid call, we must explicit cast to ReadOnly<T>
TestCalled((ReadOnly<long>)a); // explicit cast to ReadOnly<T>
// CALL USAGE 2.
// Debug vs Release call has no difference - no compiler errors
TestCalled2(a);
}
// ARG USAGE 1.
static void TestCalled(ReadOnly<long> a)
{
// invalid operations, compiler errors
a = 10L;
a += 2L;
a -= 2L;
a *= 2L;
a /= 2L;
a++;
a--;
// valid operations
long l;
l = a + 2;
l = a - 2;
l = a * 2;
l = a / 2;
l = a ^ 2;
l = a | 2;
l = a & 2;
l = a << 2;
l = a >> 2;
l = ~a;
}
// ARG USAGE 2.
#if DEBUG
static void TestCalled2(long a2_writable)
{
ReadOnly<long> a = new ReadOnly<long>(a2_writable);
#else
static void TestCalled2(long a)
{
#endif
// invalid operations
// compiler will have errors in debug configuration
// compiler will compile in release
a = 10L;
a += 2L;
a -= 2L;
a *= 2L;
a /= 2L;
a++;
a--;
// valid operations
// compiler will compile in both, debug and release configurations
long l;
l = a + 2;
l = a - 2;
l = a * 2;
l = a / 2;
l = a ^ 2;
l = a | 2;
l = a & 2;
l = a << 2;
l = a >> 2;
l = ~a;
}
}
If you often run into trouble like this then you should consider "apps hungarian". The good kind, as opposed to the bad kind. While this doesn't normally tries to express constant-ness of a method parameter (that's just too unusual), there is certainly nothing that stops you from tacking an extra "c" before the identifier name.
To all those aching to slam the downvote button now, please read the opinions of these luminaries on the topic:
Eric Lippert
Larry Osterman
Joel Spolsky
If struct is passed into a method, unless it's passed by ref, it will not be changed by the method it's passed into. So in that sense, yes.
Can you create a parameter whose value can't be assigned within the method or whose properties cannot be set while within the method? No. You cannot prevent the value from being assigned within the method, but you can prevent it's properties from being set by creating an immutable type.
The question isn't whether the parameter or it's properties can be assigned to within the method. The question is what it will be when the method exits.
The only time any outside data is going to be altered is if you pass a class in and change one of it's properties, or if you pass a value by using the ref keyword. The situation you've outlined does neither.
The recommended (well, by me) is to use an interface that provides read only access to the members. Remembering that if the "real" member is a reference type, then only provide access to an interface supporting read operations for that type -- recursing down the entire object hierarchy.
Supose that:
object x;
void GiveMeARef(ref object obj)
{
x = obj;
}
So I want that X change this value when Y is changed. For instance:
Y = new MyObject;
GiveMeARef(Y); //So x == Y;
Y = new OtherObject; // I want that X continues equals to Y, but it doesn't:\
Anyone knows how I can do this in C# if it is possible?
Sorry about my poor english
Thanks in advance
This code smells of a larger problem ... but why not just do:
var y = new MyObject();
GiveMeARef(ref y);
var z = new MyObject();
No need to reuse y.
without getting into low-level debugging techniques (like what Visual Studio uses when it's debugging your code), I don't think there's a straightforward way to do this.
What you're looking for is an alias, not a reference, and to my knowledge, that isn't supported by the CLR.
You might be able to do it by writing unsafe code, but I would suspect that there might be some significant side-effects and complications from doing this.
It really isn't clear to me what you are trying to do, but I'd be using a property:
private SomeType y;
public SomeType Y {
get { return y;}
set {
if(y!=value) {
y = value;
// run any "things to do when Y changes" code
OnYChanged();
}
}
}
public event EventHandler YChanged;
protected virtual void OnYChanged() {
EventHandler handler = YChanged;
if(handler!=null) handler(this, EventArgs.Empty);
}
Now you can watch for changes to obj.Y in 3 different ways:
in the Y setter
via the YChanged event
by subclassing and overriding OnYChanged
It seems like you want X to be a pointer to Y. Pointers aren't supported directly in C# (only in unsafe code) but you can achieve this properly by a litte hack with closures/lambda-expressions.
Try converting this VB-tip to C# (Pointer<T>-Structure)
There is no way to do what you are attempting (directly).
The closest thing I can think of would be to have Y be encapsulated inside of some other class, and have GiveMeARef() take the class instance instead of Y directly. This would look something like:
myClass.Y = new MyObject();
GiveMeARef(ref myClass);
myClass.Y = new MyObject();
Then you'd be able to still have the internal reference find Y - even though it wasn't staying exactly the same.
The easiest solution is to assign values to Y using a property, and update X in the setter function:
private MyObject m_Y = new MyObject();
public MyObject Y
{
get { return m_Y; }
set
{
m_Y = value;
X = value; // Here ...
}
}
Another solution is creating a new class, MyObjectWrapper, and deal with it instead ...
Another thing, there isn't any point of the 'ref' in GiveMeARef(ref object obj) .. it's already passed by reference.
This would also achieve the result, keeping the assignment at the time of the "new" operation, assuming that in your example you are using many different news and want X to be updated each time.
private static object x;
private static object CreateNew(Type t) {
object temp;
temp = System.Activator.CreateInstance(t);
x = temp;
return temp;
}
static void Main(string[] args) {
object o = CreateNew(typeof(int));
o = CreateNew(typeof(long));
}
Where you use reflection to create the instance of the object and assign it to the keeper variable at the same time. It very much depends on what the nature of the problem is as to which is the appropriate solution.