My application uses IronPython for users to run scripts. One such script is used for setting the members of a structure.
My Structure is as follows:
[StructLayout(LayoutKind.Sequential)]
public struct Data
{
int a;
int b;
}
I have declared a class level public object for this structure like:
public Data data = new data();
I am setting the data object as the scope variable for IronPython:
scope.SetVariable("data", data);
In the python script, I am setting the variables a and b:
data.a = 5
data.b = 10
But the variables are not changing in the C# code. I have noticed that if I use a normal integer or any other type, those variables are setting.
Is there some issue with using structures? How can I set the C# structure members from IronPython?
Use your exposed scope object to provide helper methods to scripts.
When I can't do it in IronPython that is what I do.
IronPython gives me the flexibility of a full language with ifs, fors, and whiles but sometimes the answers for integrating with the C# world are fuzzy so I just build a helper method.
You can even type the parameters because the marshalling works well across function calls.
void SetResult(int a, int b);
The minor comments are probably right you probably are setting the struct but the struct is not a pass by reference it is a pass by value.
You should understand this concept.
Here is a good SO article about it ....
What's the difference between passing by reference vs. passing by value?
You can google the concept more yourself.
Related
I want to have a vector that has a number of independent variables. In my C++ header(.h) I defined it like this:
private:
// Static data structure holding independent variables
static vector<double>* indVariables;
And in my .cpp file it is defined the same and then I'm going to have to use this vector in some other function like this:
static vector<double>* indVariables;
void fun(int m, int n)
{
for (i = 0; i < m; ++i)
{
ai = indVariables[i];
temp = exp(-n * (ai - 8.0));
}
} /* fun */
Now in C# I want to copy a set of numbers to this vector and call it back to C++ something like this:
var matu = new double[]{ 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.indVariables = matu;
How can I do it?
The first problem is because it is private I don't see it in C#. Do I have to make it public or are there other ways? And then how can I assign values to this vector?
The fact that it is private does present an issue, but, making it public won't just solve your problem I think. C# doesn't know what an std::vector is, as Richard said. I don't know much about the structure of your code, what its doing, how its being used, etc, but, if all you need is to assign a list/array of numbers to the vector, you could use a List<> in your C# code and wrap the assignment of the vector in something like this in your CLI project/file:
void Assign(Collections::Generic::List<double>^ l )
{
IndVariables->clear();
for each (double i in l)
{
IndVariables->push_back(i);
}
}
Then in your C# program, you'd write (or however you've declared your List<>):
yourCppClass.Assign(new List<double>(){0.0, 42.0, 8.0});
You could also add additional wrapper methods to manipulate or access the vector. Again, this may or may not be suitable depending on the structure of your code.
Quoting the Collections documentation for C++/CX:
In a Visual C++ component extensions (C++/CX) program, you can make
free use of Standard Template Library (STL) containers, or any other
user-defined collection type. However, when you pass collections back
and forth across the Windows Runtime application binary interface
(ABI)—for example, to a XAML control or to a JavaScript client—you
must use Windows Runtime collection types.
So, you can use STL containers as much as you like internally, but you won't be able to pass them between runtime components as they don't cross ABI boundaries.
A quick fix would be to use the Vector class available at the Platform::Collections namespace through <collection.h>.
Change your header declaration to:
public:
static Vector<Double>^ IndVariables;
Your C# component needs to change as well:
var matu = new Double[] { 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.IndVariables = matu;
This is untested code, so syntax errors or other minor issues should be present in the snippets above.
I've been working in C for the past couple of years and I've managed to get use to putting single-purpose, static variables near where they are used within my code.
While writing a very basic method that was in need of a method-scope static value, I was a bit surprised to find that the compiler didn't like that I tried to define a static object from within my method.
Googling has verified that this isn't possible within C#. Still, I'm curious why code, like the following, is completely off limits.
public int incrementCounterAndReturn()
{
static int i = 0;
return ++i;
}
Granted, this is a simplistic example that could be redefined for the same affect but that's beside the point. Method-scope, static values have their place and purpose. What design decisions have prevented such an implementation of static objects within C#?
We're on C# version 5.0 and it's 2013. I can only assume this isn't possible because of a design choice and not just because "that's complex and hard stuff to implement." Does anyone have any insider information?
The language design team is not required to provide a reason to not implement a feature. Rather, the person who wants the feature is required to make the case that the feature is the best possible way the design, implementation, test, and education teams can be spending their budgets. No one has ever successfully done so for your proposed feature.
Were I still on the design team and had this feature pitched I would point out that it is completely unnecessary. The feature in C is a known cause of developer confusion, particularly for novices, and the benefit of local vs type scope is tiny.
The underlying runtime does not provide method level static variables. In the CLR, all "static" data is defined on the type level, not method level. C# decided to not add this at the language level in its language design.
This is purely a design choice. VB.Net, which compiles to the same IL, does allow this via the Shared keyword in a Function or Sub statement (though it's handled via the compiler "promoting" the variable to a class level static variable).
Because in the CLR, static variables are associated with the TYPE. Storage for them is tied to the Type (class or stuct) they are associated with.
static variables are scoped to the class, not to an object instance. To make this work, your method must be declared static, and I believe your class must also be static (since instantiation is not relevant).
But the variable itself must be declared at the class level. C# doesn't allow you to create method-local static variables.
Worth noting: these kinds of maneuvers make it very difficult to unit test the method properly. Normally in C# one would make an ordinary class to hold such state; in fact, that's exactly how yield return works behind the scenes.
The .NET framework and languages were designed around the concept that anyone who is going to be compiling an assembly should be considered trustworthy enough to have access to all the code therein. From a semantic point of view, declaring a static variable foo within method bar would be equivalent to declaring a private static variable outside the method and accessing it within the method, provided only that one chooses as a name something which isn't used anywhere else. If one by convention combines the method name and meaning (e.g. bar_foo) one can generally avoid naming collisions pretty easily. Since the semantics are equivalent to having the variable declared outside the method, there's no need to have it declared inside.
I would like to be able to assign values to list objects without directly referencing them:
Pseudo example:
List<int> intList = new List<int> { 0 };
???? intPointer = ref intlist[0];
*intPointer = 1; // I know * isn't possible here, but it is what I'd like to do
Console.WriteLine(intList[0]);
and it would output 1.
I'm thinking that this isn't possible, but I just wanted to make sure I wasn't missing anything.
Also, I'm not looking for an example that uses unsafe, I'm curious if this is possible in managed code.
C# doesn't have a concept of "ref locals" (the CLR does though). So you'll need to wrap the values in a reference type that you can mutate. For example,
public class Ref<T> where T : struct
{
public T Value {get; set;}
}
List<Ref<int>> intRefList = new List<Ref<int>>();
var myIntRef = new Ref<int> { Value = 1 };
intRefList.Add(myIntRef);
Console.WriteLine(myIntRef.Value);//1
Console.WriteLine(intRefList[0].Value);//1
myIntRef.Value = 2;
Console.WriteLine(intRefList[0].Value);//2
Edit: C# 7.0 added ref locals but they still can't be used in this way because you can't put ref locals into an array or list.
No, this is not possible in C#.
C# does not support references to local variables, which includes references to elements of local containers.
The only way to obtain a true reference in C# (that is, not an instance of a reference type, but an actual reference to another variable) is via the ref or out parameter keywords. Those keywords cannot be used with any sort of indexed value or property, which includes elements in a List<>. You also have no direct control over these references: the compiler performs the dereferencing for you, behind the scenes.
Interestingly, the CLR does support this kind of reference; if you decompile CIL into C# you will sometimes see types like int& that are references to int. C# purposely does not allow you to use these types directly in your code.
What you're asking is not possible when using a value type such as int. You'll need an additional level of indirection; You could wrap your integer for example.
See Mutable wrapper of value types to pass into iterators for an example of that.
Regarding the static keyword.
Up to this point, via my own research, I have a general idea of what the static keyword is, but I feel that all these different descriptions and details have only confused me more. At the moment, I really don't feel that I know how to properly use "static"; it seems to be used differently between C# and VB.NET and applies differently within the language depending on what you are using it for…
While reading the MSDN article Static (Visual Basic) , many questions arose, specifically when I read this sentence:
Normally, a local variable in a procedure ceases to exist as soon as the procedure terminates. A static variable remains in existence and retains its most recent value.
Is the VB.NET version of static the same as C# or Java, is the concept the same for most languages?
If static retain a value within a class, and we are able to access that certain member, function without instantiating the class, is this safe to use loosely? In other words, should we keep a close eye when using static’s within classes? They remind me of global variables for some reason. Maybe I’m just being ignorant here and simply need more practice to understand their purpose.
What are good scenarios where using static benefits and promotes reusability of code?
In C# the static keyword is the same as the shared keyword in VB.NET. Namely, from Static Classes and Static Class Members (C# Programming Guide):
Static classes and class members are used to create data and functions
that can be accessed without creating an instance of the class.
In VB.NET static works very differently, as it applies to variables, not types.
I do not know if there is a C# equivalent for this behavior.
1) Is the VB.NET version of static the same as C# or Java, and is the concept
the same for most languages?
It's different. shared is the same, though.
2) If static retain value within a class, and we are able to access
that certain member, function without instantiating the class – Is
this safe to use loosely? In other words, should we keep a close eye
when using static’s within classes? They remind me of global
variables for some reason, maybe I’m just being ignorant here and
simply need more practice to understand their purpose.
Be very careful, they are global to the application domain.
3) What are good scenarios where using static benefits and promotes
reusability of code?
I use static lists to cache sets of data that are used to populate dropdown lists so that I don't have to keep hitting SQL Server as one example.
The other answers dealt with the C# usages of static, so I'll talk about Static in VB.NET since you referenced an MSDN article about it. When you make a Static local variable in VB.NET, the compiler will translate that to a class-level variable that can only be referenced by code in the function in which the variable is declared in code. Whether said variable is instance or shared depends on the containing function. For example, this code:
Public Class StaticTest
Public Function Process(value As Integer) As Integer
Static lastValue As Integer
Dim result As Integer
If value > 0 Then
result = value
lastValue = value
Else
result = lastValue
End If
Return result
End Function
End Class
Decompiles to something like this:
Public Class StaticTest
' Methods
<DebuggerNonUserCode> _
Public Sub New()
End Sub
Public Function Process(ByVal value As Integer) As Integer
If (value > 0) Then
Dim result As Integer = value
Me.$STATIC$Process$20188$lastValue = value
Return result
End If
Return Me.$STATIC$Process$20188$lastValue
End Function
' Fields
Private $STATIC$Process$20188$lastValue As Integer
End Class
I noticed that if I set lastValue to value on entrance into the function, the compiler also created some sort of initialization code and extra fields, so there are some cases where Static locals do generate some extra code.
I would recommend avoiding using Static locals because I find them more confusing then helpful when compared to the alternative, actually declaring a class-level instance variable. The tradeoffs of Statics are:
For:
Cannot be accessed in another function
Against:
Cannot be initialized in constructor (but can be initialized inline with their declaration, which gives the extra init field/code I mentioned above)
Cannot be located according to your typcial placement of class locals in code
Look like locals but are not
VB.NET's shared is the same as C#'s static. C#'s static is pretty much the same as static in Java and most other languages. The concepts carry over.
This is a yes and no kind of question. You don't want to just randomly throw statics around without knowing what you're doing. However, they can be useful for a lot of situations (more on that in #3). They are not really like global variables because they are still "namespaced" and organized by the class they belong to.
Static members are typically used for utility methods and classes. For example, C# implements most of the Math library as static methods, since they're just doing computations and have no other side effects. As a general rule, if your method has no side effects, and all of the data it needs to do its job comes in as parameters. You can also use static properties if you want to share some data between instances of a class (for example, to track how many times a given method has been called, or something similar). Static also has some memory usage benefits, since it allows you to create only one instance of a class or method to share throughout the application, rather than creating new copies for each usage. You also use static classes for extension methods, but that's a whole other discussion.
You didn't ask specifically, but it's worth mentioning the downsides. The biggest reason to avoid static is maintainability. You cannot inherit or extend static classes easily, which is a major thing to think about. So long as you stick to the composition over inheritance rule, this isn't necessarily a deal-breaker, but the lack of inheritance and polymorphism for static classes is a major drawback. That one issue by itself leads a lot of people to suggest avoiding static in all cases.
The title is obvious, I need to know if methods are serialized along with object instances in C#, I know that they don't in Java but I'm a little new to C#. If they don't, do I have to put the original class with the byte stream(serialized object) in one package when sending it to another PC? Can the original class be like a DLL file?
No. The type information is serialized, along with state. In order to deserialize the data, your program will need to have access to the assemblies containing the types (including methods).
It may be easier to understand if you've learned C. A class like
class C
{
private int _m;
private int _n;
int Meth(int p)
{
return _m + _n + p;
}
}
is essentially syntactic sugar for
typedef struct
{
int _m;
int _n;
// NO function pointers necessary
} C;
void C_Meth(C* obj, int p)
{
return obj->_m + obj->_n + p;
}
This is essentially how non-virtual methods are implemented in object-oriented languages. The important thing here is that methods are not part of the instance data.
Methods aren't serialized.
I don't know about your scenario, but putting in a library (assembly / dll) and using that in the other end to deserialize gets you all.
Ps. you probably should create some ask some more questions with the factors involved in your scenario. If you are intending to dynamically send & run the code, you can create awful security consequences.
I was confused when .NET first came up with serialization. I think it came from the fact that most books and guides mention that it allows you to serialize your 'objects' as XML and move them around, the fact is that you are actually hydrating the values of your object so you can dehydrate them latter. at no point your are saving your whole object to disk since that would require the dll and is not contained in the XML file.