I'm trying to wrap my head around Ruby variables and thought it might be good to see them in terms of C#
could someone tell me the C# equivalent of Ruby's (for example is ## == public static variable?):
$ global variable# instance variable## class variable[a-z] local variable[A-Z] constant
any other types of variables I'm missing?
Could someone also explain how #instance variables are used/function?
at first I thought it was some global variable in the instance of a class, but then i saw it used with a scope like a local variable in the instance's method.
here's is an example from the 'well grounded rubyist'
class C
def show_var
#v = "i am an instance variable initialized to a string"
puts #v
end
#v = "instance variables can appear anywhere..."
end
C.new.show_var
if I wanted 'v' to be the same variable from anywhere in the class instance, what is the Ruby mechanism for doing this?
C# does not use sigils for variables.
The "equivalent" C# variable depends entirely on how the variable/member is defined. Note that there are differences even between the "equivalent" forms.
However, there are a number of naming conventions that are encouraged to be followed. The exact conventions used vary by project and may differ from the names I chose below, which reflect my conventions - do not use "class" or "instance" or "local" in real variable names.
Examples:
class MyClass: IMyInterface {
// "const" makes it constant, not the name
public const int CONSTANT = 42;
// static member variable - somewhat like Ruby's ##variable
private static int classVariable;
public static int ExposedClassVariable; // but use properties
// #variable - unlike Ruby, can be accessed outside "self" scope
int instanceVariable;
public int ExposedInstanceVariable; // but use properties
void method (int parameter) {
int localVariable;
}
}
C# does not have "global variables in a shared namespace", but static member variables can be accessed by a stable path which means they can be effectively abused as global variables.
Related
In Delphi you can declare a constant in a method and assign it a value in that same method. The idea is that next time you are in this method, the const will still have the same value that you last assigned it.
It looks like this in Delphi :
(I don't have Delphi here so it is untested, sorry about that, but it is enough to demonstrate what I mean)
procedure Form1.test;
const
AssignableConst: Integer = 0;
begin
ShowMessage(AssignableConst);
inc(AssignableConst);
end;
Every time you call the procedure test the messagebox will show the last value + 1
This example is completely useless I know that it is just to show how an assignable const works in Delphi.
Is there an equivalent for this in c# ?
I don't want a solution that involves private variables in the class, it has to stay inside the method.
My question is about scope. Nothing else. I don't care that the value is part of the state of the object. That is not important. What is important is that I need a variable that is only accessible from the scope of a method, nowhere else.
In Delphi this can be done by using an assignable const, so how can I do this in C#?
I don't want a solution that involves private variables in the class, it has to stay inside the method.
But the value is part of the state of the object (or type, for a static method) - so it makes sense for it to be a field declared in the object.
There's no equivalent to this in C#. The best you can do is have a private variable and document that it should only be used from a specific method. (You could write Roslyn-based tests for that if you really want.)
The closest you can get is:
class MyClass
{
static Action CreateCounter()
{
int counter = 0;
return () => {
Show(counter);
counter++;
};
}
Action showAndIncrementCounter = CreateCounter();
public ShowAndIncrementCounter()
{
showAndIncrementCounter();
}
}
But I still recommend the simple solution of using an instance field for the counter and just not accessing it from outside the method.
In C#, if I have the following struct:
internal struct myStruct : IDisposable
{
public int x;
public void Dispose()
{
x = 0;
}
}
then do this in Main:
using (myStruct myStruct = new myStruct())
{
myStruct.x = 5;
}
it fails saying that myStruct is readonly. That makes sense as myStruct is a value-type.
Now if I add the folling function to the struct:
public void myfunc(int x)
{
this.x = x;
}
and change the Main code to this:
using (myStruct myStruct = new myStruct())
{
myStruct.myfunc(5);
Console.WriteLine(myStruct.x);
}
it works. Why ?
The short answer is "because the C# specification says so". Which, I admit, may be a bit unsatisfying. But that's how it is.
The motivation is, I'm sure, as commenter Blogbeard suggests: while it's practical to enforce read-only on the field access, it's not practical to do so from within a type. After all, the type itself has no way to know how a variable containing a value of that type was declared.
The key part of the C# specification (from the v5.0 spec) is here, on page 258 (in the section on the using statement):
Local variables declared in a resource-acquisition are read-only, and must include an initializer. A compile-time error occurs if the embedded statement attempts to modify these local variables (via assignment or the ++ and operators), take the address of them, or pass them as ref or out parameters.
Since in the case of a value type, the variable itself contains the value of the object rather than a reference to an object, modifying any field of the object via that variable is the same as modifying the variable, and is so a "modification via assignment", which is specifically prohibited by the specification.
This is exactly the same as if you had declared the value type variable as a field in another object, with the readonly modifier.
But note that this is a compile-time rule, enforced by the C# compiler, and that there's no way for the compiler to similarly enforce the rule for a value type that modifies itself.
I will point out that this is one of many excellent reasons that one should never ever implement a mutable value type. Mutable value types frequently wind up being able to be modified when you don't want them to be, while at the same time find themselves failing to be modified when you do want them to be (in completely different scenarios from this one).
If you treat a value type as something that is truly a value, i.e. a single value that is itself never changing, they work much better and find themselves in the middle of many fewer bugs. :)
I am trying to extract debug information from a compiled C program with C#, and need to store the global variables.
If I have the variable:
const unsigned char * volatile MyVariable;
the name of the variable will be MyVariable, and the type is unsigned char. what will be const and volatile. Are they part of the type?
I have to represent a variable with a class and I am lost on how to construct it. This is how I have represented it right now:
public class MyVariable
{
public string Name;
public string Type;
public bool IsArray;
public bool IsPointer;
public bool IsConstant;
public bool IsVolatile;
// etc...
public int Size; // in bytes
}
Should I make volatile and const part of the type? What are they? Attributes?
Edit
Sorry I think I did not explained my self correctly. my question should have been how should I construct MyVariable class I know what the const keyword does to a variable and also the volatile. I use the volatile keyword when I create a variable that will be accessed by multiple threads for example.
Anyways so based on the answers I should be constructing my class as:
public class MyVariable
{
public string Name;
public string Type;
public string[] TypeQualifiers;
public int Size; // in bytes
}
where TypeQualifiers will be an array of those keywords (type qualifiers). Thanks a lot for the help.
const and volatile are both type qualifiers, although they are completely independent.
The const keyword specifies that the object or variable cannot be changed within the code.
The volatile qualifier declares the data can have its value changed in ways outside the control or detection of the compiler, preventing the compiler from applying any optimizations on the code (such as storing the object's value in a register rather than the memory, where it may have changed).
A variable which is both const and volatile means that it is guaranteed not to be changed in the current code, but that does not mean that it cannot be changed externally.
EDIT: As a sidenote, unsigned is a type modifiers in C, just like signed and long.
I suggest that you also have independent type fields such as IsSigned, IsUnsigned and IsLong in addition to the type itself (int, char, etc...).
Yout project will give you some trouble, since you are apparently not really familiar with C, and most importantly, do not have a good language reference at hand...
const, volatile and restrict are "type qualifiers". For example, unsigned char is an unqualified type. The qualifiers give the compiler additional hints on how to handle the memory. They can be attached in just about any combination.
Start by reading section 6.7 (Declarations) of latest online C Standard.
You're going to have a hard time capturing all the nuances of C declaration syntax in a flat data structure such as in your example. The concept of "type" can get pretty complicated, such as
int *(*(*f[N])())[M];
where f has type "N-element array of pointers to functions returning pointers to M-element arrays of pointers to int". You'll probably never see anything that obnoxious in real code, but it illustrates the difficulty of extracting type information from a declaration.
What is the equivalent of Java's final in C#?
The final keyword has several usages in Java. It corresponds to both the sealed and readonly keywords in C#, depending on the context in which it is used.
Classes
To prevent subclassing (inheritance from the defined class):
Java
public final class MyFinalClass {...}
C#
public sealed class MyFinalClass {...}
Methods
Prevent overriding of a virtual method.
Java
public class MyClass
{
public final void myFinalMethod() {...}
}
C#
public class MyClass : MyBaseClass
{
public sealed override void MyFinalMethod() {...}
}
As Joachim Sauer points out, a notable difference between the two languages here is that Java by default marks all non-static methods as virtual, whereas C# marks them as sealed. Hence, you only need to use the sealed keyword in C# if you want to stop further overriding of a method that has been explicitly marked virtual in the base class.
Variables
To only allow a variable to be assigned once:
Java
public final double pi = 3.14; // essentially a constant
C#
public readonly double pi = 3.14; // essentially a constant
As a side note, the effect of the readonly keyword differs from that of the const keyword in that the readonly expression is evaluated at runtime rather than compile-time, hence allowing arbitrary expressions.
It depends on the context.
For a final class or method, the C# equivalent is sealed.
For a final field, the C# equivalent is readonly.
For a final local variable or method parameter, there's no direct C# equivalent.
What everyone here is missing is Java's guarantee of definite assignment for final member variables.
For a class C with final member variable V, every possible execution path through every constructor of C must assign V exactly once - failing to assign V or assigning V two or more times will result in an error.
C#'s readonly keyword has no such guarantee - the compiler is more than happy to leave readonly members unassigned or allow you to assign them multiple times within a constructor.
So, final and readonly (at least with respect to member variables) are definitely not equivalent - final is much more strict.
As mentioned, sealed is an equivalent of final for methods and classes.
As for the rest, it is complicated.
For static final fields, static readonly is the closest thing possible. It allows you to initialize the static field in a static constructor, which is fairly similar to static initializer in Java. This applies both to constants (primitives and immutable objects) and constant references to mutable objects.
The const modifier is fairly similar for constants, but you can't set them in a static constructor.
On a field that shouldn't be reassigned once it leaves the constructor, readonly can be used. It is not equal though - final requires exactly one assignment even in constructor or initializer.
There is no C# equivalent for a final local variable that I know of. If you are wondering why would anyone need it: You can declare a variable prior to an if-else, switch-case or so. By declaring it final, you enforce that it is assigned at most once.
Java local variables in general are required to be assigned at least once before they are read. Unless the branch jumps out before value read, a final variable is assigned exactly once. All of this is checked compile-time. This requires well behaved code with less margin for an error.
Summed up, C# has no direct equivalent of final. While Java lacks some nice features of C#, it is refreshing for me as mostly a Java programmer to see where C# fails to deliver an equivalent.
Java class final and method final -> sealed.
Java member variable final -> readonly for runtime constant, const for compile time constant.
No equivalent for Local Variable final and method argument final
http://en.csharp-online.net/CSharp_FAQ:_What_are_the_differences_between_CSharp_and_Java_constant_declarations
C# constants are declared using the const keyword for compile time constants or the readonly keyword for runtime constants. The semantics of constants is the same in both the C# and Java languages.
sealed
Why does C# not allow const and static on the same line? In Java, you must declare a field as 'static' and 'final' to act as a constant. Why does C# not let you declare const's as final?
I make the further distinction that in Java, every interface is public and abstract, whether this is explicitly declared or not. Aren't const's effectively static in nature? WHy does C# balk at this?
const and static really do mean different things, different storage mechanism, different initialisation. static is read/write, therefore must have memory allocated for storage and must be initialised at runtime. A static can be initialised with a literal value or an expression. In contrast, a const is immutable and must be initialised with a compile time constant (typically a literal value, or an expression that can be fully evaluated at compile time). The value is known at compile time so it can be embedded directly in the generated code, therefore requires no storage to be allocated at runtime.
Constants by their nature are static, so that would be redundant.
As said before, static final in Java is the same as static readonly in C#. In fact, you are saying that this member is static and its content can't be changed. Also you can specify in both cases the value from static constructor.
But const in C# is completely different thing. It's more along the lines of constants in C (DEFINE directives) but with OOP in mind. It's static because it's constant - every instance would have this constant with the same value, no constructor can set it. Also it's possible that someone would like to access the constant without having to create an instance. When you think about it non-static constant just doesn't make sense. You can almost say that constants are not part of an object - they just use it to provide context, a strong name.
Java doesn't have an equivalent to const. You can read somewhere that static final is equivalent to DEFINE but that's just so vague. Completely different mechanism, nothing in common but in the end result in the code is the same - better maintainability and readability of the code.
You just have to stop thinking about constants in C# as static members because they are not. Think of them as OOP version of DEFINE. When you consider encapsulation only reason for final and readonly fields is to prevent your own code from accidently changing its value. And that doesn't sound like constant to me.
Sumary:
final = readonly
static final = static readonly
N/A = const
It is true that a C# const implies static BUT, C# has an equivalent to Java's final keyword in the keyword readonly.
So, in fact, C# allows a const final, it is static readonly in C#.
Because allowing and not requiring modifiers that are inherent can cause confusion. If you see
static const int A = 3
const int B = 5
you may believe that they are 2 different kinds of constants.
Even VB 2008 (which can be very verbose if you wish) doesn't allow that.