i am writing a simple code by using ref keyword. As i understand struct can be really slow on copying things. In order to make it faster you should use ref. So i wrote this simple code below.
using System;
namespace ConsoleApplication4
{
class Program
{
public static void returns(ref s s1)
{
for (int i = 0; i < 100;i++)
{
s1.z += i;
}
}
static void Main(string[] args)
{
s s1 = new s();
returns(ref s1);
}
}
}
it gave me the error "Error 1 Inconsistent accessibility: parameter type 'ref is less accessible than method". I checked one of stackoverflow question. Using ref seemed like that. What is my mistake here. Can you give me any advice.
Thanks in advance.
Likely the type s is not a public type.
oh thanks i just forgot to type these lines to here.
public struct s
{
public int z;
}
i did this private not i changed to a public. One of my friend suggest me to do private struct blah and do property of struct public. Is it false logic.
Related
Trying a shot to a little advanced text adventure here, I have an inventory class. (isn't an error) and it all works great!
I'm trying to implement a feature of an input. That it just leads to input, and then returns the arguments back to that class. I thought it would be easy. Turned out a 'void' method can't return something. I don't know what I should use then.
I searched a bit on Google but can't find google, and the answers on here are all XML or more experienced programmers. There are also a few simpler once, but those are unanswered.
This is my Program class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Inventory_system_test
{
class Program
{
//Objects
static private Inventory inv = new Inventory();
//strings
static private string args;
//variables
static void Main(string[] args)
{
Write("Do you want to kill dave?");
input();
}
static public void input()
{
bool done = false;
Writen("Enter a command: ");
args = Console.ReadLine();
while (!done)
{
if (args.Contains("add inv "))
{
args = args.Split()[2];
inv.additem(args);
}
else if (args.Contains("remove inv "))
{
args = args.Split()[2];
inv.removeitem(args);
}
else if (args.Contains("see inv"))
{
Write("INVENTORY:");
inv.getinv();
}
else if (args == "close")
{
Environment.Exit(0);
}
else
{
done = true;
return args; ///**Here is the error ofcourse.**
}
}
} //Input files things :)
#region Easy Commands (Write, Sleep)
//Write to console
public static void Write(string writev)
{
Console.WriteLine(writev);
}
//Sleep for 'int sleeptime' in milliseconds
public static void Sleep(int sleeptime)
{
System.Threading.Thread.Sleep(sleeptime);
}
public static void Writen(string writen)
{
Console.Write(writen);
}
#endregion
}
}
I'm getting to understand scripting more and more, and that's just by asking question and searching Googles, I really love the people on Stackoverflow! Thank you all for your help!
So uh.. how would I go and do this?
There aren't many methods.. And I wouldn't know what to do from here.
Turned out a 'void' method can't return something. I don't know what I should use then.
You should use a method which is declared to return the kind of information you want to return! When a method is void, that specifically means it's not meant to return anything.
In this case it looks like you're trying to return the value of args, which is a string variable, so you want:
public static string input()
Additionally:
You should follow .NET naming conventions
There's no reason for your args variable to be static - it would better as a local variable within your method
args is an odd name for this variable anyway, in my view. Given that you're asking for a command, why not use command as the variable name?
I suggest you read the MSDN page on methods or look in a good book about C# to learn more about return types, parameters and so on.
From void (C# Reference)
When used as the return type for a method, void specifies that the
method does not return a value.
But your input method returns a value so..
Console.ReadLine() methods retursn a string so your args is looks like a string. That's why you should change your return type as a string like;
public static string input()
{
}
You declare args as being of type string, so that's what you should return:
static public string input()
{
...
return args;
}
This is maybe an obvious question but I have been googling for 2 hours and can't figure it out. So I've got a class in C++ that looks like this:
class MyClass
{
public:
static void Function(float& r) { r = 10; }
};
I have an interop wrapper class that looks like this:
public ref class Wrapper
{
public:
static void WrappedFunction(float& r) { MyClass::Function(r); }
};
And now I want to call it from C#, like this:
float r;
Wrapper.WrappedFunction(ref r);
However I get a compile error on the C# side which says this:
cannot convert from 'ref float' to 'float*'
I have a vague notion that I need to do something in the Wrapper class but I don't know what. Also, I know this use case is trivial with dllimport/pinvoke but I want to wrap this with C++/CLI for performance reasons.
Any help is greatly appreciated!
Wrapper class needs to be
public ref class Wrapper
{
public:
static void WrappedFunction(float% r)
{ float copy = r; MyClass::Function(copy); r = copy; }
};
References defined with % work almost exactly like ones defined using &, except they work together with the garbage collector.
Another option is
public ref class Wrapper
{
public:
static void WrappedFunction(float% r)
{ pin_ptr<float> p = &r; MyClass::Function(*p); }
};
Which will pin the object in memory preventing the garbage collector from using it, but have the native code work directly on the managed variable. Not usually important, but if you had another thread needing to see intermediate values, this is how.
In my c# application i receive pointer to c++ struct in callback/delegate. I'm not sure if class can do the trick but just casting c++ pointer to appropriate c# struct works fine, so I'm using c# struct for storing data.
Now I want to pass reference to struct for further processing
I can't use class because it probably will not "map" perfectly to c++ struct.
I don't want to copy struct for better latency
How can I do that?
This example demonstrates that struct is passed by value, not by reference:
using System;
namespace TestStruct
{
struct s
{
public int a;
}
class Program
{
static void Main(string[] args)
{
s s1 = new s
{
a = 1
};
Foo(s1);
Console.WriteLine("outer a = " + s1.a);
}
private static void Foo(s s1)
{
s1.a++;
Console.WriteLine("inner a = " + s1.a);
}
}
}
Output is:
inner a = 2
outer a = 1
It sounds like you just want to use ref to pass the struct by reference:
private static void Foo(ref s s1)
{
s1.a++;
Console.WriteLine("inner a = " + s1.a);
}
And at the call site:
Foo(ref s1);
See my article on parameter passing in C# for more details.
Note that other than for interop, I would normally strongly recommend against using mutable structs like this. I can understand the benefits here though.
I want to use a function from another class within a new function which I will call from main. I am trying to do this as below, but get an error:
Error The name 'Class1' does not exist in the current context.
Actually, in my code I use different names, but its just to illustrate the structure and to make it easier to read for you.
public class Class1
{
public static int[] Function1()
{
// code to return value
}
}
public class Class2
{
public static int Function2()
{
int[] Variable = Class1.Function1();
//other code using function1 value
}
}
Actually, in my code I use different names, but its just to illustrate the structure and to make it easier to read for you.
Unfortunately you've made it so easy to read that you have eliminated the problem entirely! The code you posted does not contain an error and is perfectly valid.
The error message is very clear; from wherever you are actually calling the code, "Class1" (or whatever it may be) is not in scope. This may be because it is in a different namespace. It may also be a simple typo in your class name. Does your code actually look something like this?
namespace Different
{
public class Class1
{
public static int[] Function1()
{
// code to return value
}
}
}
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
// Error
var arr = Class1.Function();
// you need to use...
var arr = Different.Class1.Function();
}
}
}
That's the best I got until you post the actual code.
Consider the following code:
using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var square = new Square(4);
Console.WriteLine(square.Calculate());
}
}
class MathOp
{
protected MathOp(Func<int> calc) { _calc = calc; }
public int Calculate() { return _calc(); }
private Func<int> _calc;
}
class Square : MathOp
{
public Square(int operand)
: base(() => _operand * _operand) // runtime exception
{
_operand = operand;
}
private int _operand;
}
}
(ignore the class design; I'm not actually writing a calculator! this code merely represents a minimal repro for a much bigger problem that took awhile to narrow down)
I would expect it to either:
print "16", OR
throw a compile time error if closing over a member field is not allowed in this scenario
Instead I get a nonsensical exception thrown at the indicated line. On the 3.0 CLR it's a NullReferenceException; on the Silverlight CLR it's the infamous Operation could destabilize the runtime.
It was a compiler bug that has been fixed. The code should never have been legal in the first place, and if we were going to allow it, we should have at least generated valid code. My bad. Sorry about the inconvenience.
It's not going to result in a compile-time error because it is a valid closure.
The problem is that this is not initialized yet at the time the closure is created. Your constructor hasn't actually run yet when that argument is supplied. So the resulting NullReferenceException is actually quite logical. It's this that's null!
I'll prove it to you. Let's rewrite the code this way:
class Program
{
static void Main(string[] args)
{
var test = new DerivedTest();
object o = test.Func();
Console.WriteLine(o == null);
Console.ReadLine();
}
}
class BaseTest
{
public BaseTest(Func<object> func)
{
this.Func = func;
}
public Func<object> Func { get; private set; }
}
class DerivedTest : BaseTest
{
public DerivedTest() : base(() => this)
{
}
}
Guess what this prints? Yep, it's true, the closure returns null because this is not initialized when it executes.
Edit
I was curious about Thomas's statement, thinking that maybe they'd changed the behaviour in a subsequent VS release. I actually found a Microsoft Connect issue about this very thing. It was closed as "won't fix." Odd.
As Microsoft says in their response, it is normally invalid to use the this reference from within the argument list of a base constructor call; the reference simply does not exist at that point in time and you will actually get a compile-time error if you try to use it "naked." So, arguably it should produce a compile error for the closure case, but the this reference is hidden from the compiler, which (at least in VS 2008) would have to know to look for it inside the closure in order to prevent people from doing this. It doesn't, which is why you end up with this behaviour.
How about this:
using System;
using System.Linq.Expressions;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var square = new Square(4);
Console.WriteLine(square.Calculate());
}
}
class MathOp
{
protected MathOp(Expression<Func<int>> calc) { _calc = calc.Compile(); }
public int Calculate() { return _calc(); }
private Func<int> _calc;
}
class Square : MathOp
{
public Square(int operand)
: base(() => _operand * _operand)
{
_operand = operand;
}
private int _operand;
}
}
Have you tried using () => operand * operand instead? The issue is that there's no certainty that _operand will be set by the time you call the base. Yes, it's trying to create a closure on your method, and there's no guarantee of the order of things here.
Since you're not setting _operand at all, I'd recommend just using () => operand * operand instead.