I wonder if there is a way to use a reference of a var like 'ref' but not in a method.
exemple :
using System;
using System.Collections;
using System.Collections.Generic;
public class Class3
{
struct myStruct
{
public bool structBool;
public int structInt;
public myStruct(bool _structBool, int _structInt)
{
structBool = _structBool;
structInt = _structInt;
}
}
myStruct currentTask;
int value1,value2;
bool mybool, isProcessing;
Queue<myStruct> myTask = new Queue<myStruct>();
void main()
{
//these two lines don't work due to the "ref" but I'm looking for something work like this
if (value1 > value2) myTask.Enqueue(new myStruct(mybool,ref value1));
if (value2 > value1) myTask.Enqueue(new myStruct(mybool,ref value2));
MyFunction();
}
void MyFunction()
{
if (myTask.Count > 0)
{
if (!isProcessing)
{
currentTask = myTask.Dequeue();
isProcessing = true;
}
else
{
currentTask.structInt++; // here I need to catch my var (value1 or value2)
}
}
}
}
I tried to put the values into an array but I think it's a bad way. I tried lot of other stuff but nothing work properly.
You can change the constructor to pass those parameters by reference like so:
public myStruct(bool _structBool, ref int _structInt),
The problem is that invoking this line
currentTask.structInt++;
still wouldn't change the original variables (value1, value2). Check the solution in the answer here: https://stackoverflow.com/a/13120988/775018
Usually when you want to give multiple values to a constructor (or even a method), it's very acceptable that you give them as part of a class:
public class Args
{
public int Value { get; set; }
}
So now you can do this:
Args args1 = new Args { Value = 10 };
Args args2 = new Args { Value = 34 };
// Obviously, your structs or classes should accept Args class as input parameter
var struct1 = new MyStruct(true, args1);
var struct2 = new MyStruct(false, args2);
Now modifications to Args.Value1 and/or Args.Value2 will be available for the struct constructor callers.
Related
This question already has answers here:
Optional delegates in C# [duplicate]
(4 answers)
Closed 9 years ago.
I need to call a delegate method passed as a parameter, but since this parameter is optional I want to set the default value to a method implemented in the "destination" class.
This is an example where it almost works as expected:
public class AgeCalculator
{
public void SetAge(Client client, Func<int, int> getAge = default(Func<int, int>))
{
client.Age = getAge != default(Func<int, int>) ? getAge(client.Id) : this.getAge(client.Id);
}
private int getAge(int clientId) {
return 10;
}
}
And then..
class Program
{
static void Main(string[] args)
{
AgeCalculator calculator = new AgeCalculator();
Client cli1 = new Client(1, "theOne");
calculator.SetAge(cli1);//Sets 10
calculator.SetAge(cli1, getAge);//Sets 5
}
private static int getAge(int clientId) {
return 5;
}
}
The question now; what is the default value that has to be setted to avoid asking about the delegate value?
Tried "public void SetAge(Client client, Func getAge = this.getAge)" with no luck.
Is there a tag or different definition needed on AgeCalculator.getAge?, should I use dynamic methods?
Thanks in advance.
Note: The real scenario involves more complex logic in a TDD oriented project, this is a sample to summarize the situation.
Default values for method arguments must be compile-time constants. Writing default(Func<...>) is just verbose syntax for null, which is the default value for reference types (as a delegate, Func is a reference type) and the only default value you can use in this context.
However, you can do much better with the old-fashioned way of offering two overloads for the method:
public void SetAge(Client client)
{
// Select any default value you want by calling the other overload with it
SetAge(client, this.getAge);
}
public void SetAge(Client client, Func<int, int> getAge)
{
client.Age = getAge(client.Id);
}
This is basically doing what you are asking, the only thing is that the hints given by VS won't show that a function is being used as the default if null isn't used. If that isn't a problem then this solution is logically as close as you are going to get.
public class AgeCalculator
{
public void SetAge ( Client client , Func<int , int> getAge = null)
{
// assigns this.getAge to getAge if getAge is null
getAge = getAge ?? this.getAge;
client.Age = getAge( client.Id );
}
private int getAge ( int clientId )
{
return 10;
}
}
You can also make this something that allows a variable method to be plugged in if you want to change the default setter dynamically. It is identical logic just another way, this is beneficial if you know you will use the same function multiple times in a row.
public class AgeCalculator
{
public void SetAge ( Client client )
{
client.Age = GetAge( client.Id );
}
private Func<int,int> _getAge;
public Func<int,int> GetAge
{
private get
{
if(_getAge == null)
_getAge = getAge;
return _getAge;
}
set
{
if(value == null)
_getAge = getAge;
else
_getAge = value;
}
}
private int getAge ( int clientId )
{
return 10;
}
}
//assume we are in main
var cl = new Agecalculator();
var client = new Client(1,"theOne");
var client2 = new Client(2,"#2");
cl.SetAge(client); //set 10
cl.GetAge = getAge;
cl.SetAge(client); //set 5
cl.SetAge(client2); //set 5
How I can to pass a reference as a parameter to Async method in Windows Store App ? I'm looking for something like this:
var a = DoThis(ref obj.value);
public async Task DoThis(ref int value)
{
value = 10;
}
But error:
Async methods cannot have ref or out parameters
Has any another way?
Note:I need to pass exactly obj.value. This method would be used by different types of objects, by same type of objects, by one object, but I will pass obj.val_1, obj.val_2 or obj.val_10. All values will be same type (for ex string)
If you don't care about a little overhead and possibly prolonged lifetime of your objects, you could emulate the ref behavior by passing a setter and a getter method to the function, like this:
public async Task DoStuff(Func<int> getter, Action<int> setter)
{
var value1 = getter();
await DoSomeOtherAsyncStuff();
setter(value1 * value1);
}
And call it like this:
await DoStuff(() => obj.Value, x => obj.Value = x);
You could directly pass the object itself and set the value of the corresponding property inside the method:
var a = DoThis(obj);
public async Task DoThis(SomeObject o)
{
o.value = 10;
}
And if you do not have such object simply write one and have the async method take that object as parameter:
public class SomeObject
{
public int Value { get; set; }
}
You can always use the Task<> class and return the desired value. Then Your code would look something like:
var a = DoThis(obj.value);
obj.value = a.Result;
public async Task<int> DoThis(int value)
{
int result = value + 10; //compute the resulting value
return result;
}
EDIT
Ok, the other way to go with this that I can think of is encapsulating the update of the given object's member in a method and then passing an action invoking this method as the task's argument, like so:
var a = DoThis(() => ChangeValue(ref obj.value));
public void ChangeValue(ref int val)
{
val = 10;
}
public async Task DoThis(Action act)
{
var t = new Task(act);
t.Start();
await t;
}
As far as I tested it the change was made in the child thread, but still it's effect was visible in the parent thread. Hope this helps You.
You can't do this as you have it (as you know). So, a few work arounds:
You can do this by passing the initial object since it will be a reference type
var a = DoThis(obj);
public async Task DoThis(object obj) //replace the object with the actual object type
{
obj.value = 10;
}
EDIT
Based upon your comments, create an interface and have your classes implement it (providing it's always the same type you want to pass). Then you can pass the interface which is shared (maybe over kill, depends on your needs, or even unrealistic amount of work).
Or, provide a base class with the property! (I don't like this suggestion but since you're asking for something which can't be done it may suffice although I don't recommend it).
An example of the interface is here (not using what you have, but close enough using a Colsone App)
using System;
namespace InterfacesReferenceTypes
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
DoThis(mc);
Console.WriteLine(mc.Number);
Console.ReadKey();
}
static void DoThis(IDemo id)
{
id.Number = 10;
}
}
class MyClass : IDemo
{
//other props and methods etc
public int Number { get; set; }
}
interface IDemo
{
int Number { get; set; }
}
}
EDIT2
After next comments, you will have to still use an interface, but re assign the value afterwards. I'm sure there is a better way to do this, but this works:
using System.Text;
namespace InterfacesRerefenceTypes
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
Console.WriteLine(mc.Number);
mc.val1 = 3;
mc.val2 = 5;
mc.Number = mc.val2;
DoThis(mc);
mc.val2 = mc.Number;
Console.WriteLine(mc.val2);
Console.ReadKey();
}
static void DoThis(IDemo id)
{
id.Number = 15;
}
}
class MyClass : IDemo
{
public int val1 { get; set; }
public int val2 { get; set; }
public int Number { get; set; }
}
interface IDemo
{
int Number { get; set; }
}
}
have a php code like this,going to convert it in to C#.
function isValid($n){
if (preg_match("/\d+/",$n) > 0 && $n<1000) {
return true;
}
return false;
}
Here is my try,BUT error shown Error is "expected class, delegate, enum, interface or struct error C#"
public string IsValidate(string Item)
{
string Result = Item;
try
{
Result = System.Text.RegularExpressions.Regex.Replace(InputTxt, #"(\\)([\000\010\011\012\015\032\042\047\134\140])", "$2");
}
catch(Exception ex)
{
console.WriteLine(ex.Message)
}
return Result;
}
What is the error,Is there any other way to implement this better than my try ?
i got this snippet from here code
You haven't define this method inside a class/struct that is why you are getting this error. You may define this method inside a class.
public class MyValidator
{
public string IsValidate(string Item)
{
//Your code here
}
}
Later you can use it like:
MyValidator validator = new MyValidator();
validator.IsValid("Your string");
Also you are missing semicolon at the end of the Console.Write statement, plus 'c' for Console should be in uppercase
Edit:
Since in your php code, it looks like you are trying to see if the string passed is an integer and it is less than 1000, you may use the int.TryParse like the following:
public class MyValidator
{
public bool IsValidate(string Item)
{
string Result = Item;
int val;
if (int.TryParse(Item, out val) && val > 0 && val < 1000)
{
return true;
}
else
{
return false;
}
}
}
In you main method you can do:
static void Main()
{
MyValidator validator = new MyValidator();
Console.WriteLine(validator.IsValidate("asdf123")); // This will print false
Console.WriteLine(validator.IsValidate("999")); //This will print true
Console.WriteLine(validator.IsValidate("1001")); //This will print false
}
In C# a method must be placed inside a class or struct:
public class Validator {
public string IsValidate(string item) {
...
}
}
In this case I would probably translate it like this:
public static class Validator {
public static bool IsValid(string item) {
int value;
return int.TryParse(item, out value)
&& value > 0 && value < 1000;
}
}
You could define your function inside a static class such that you dont have to create an instance of it before invoking the function. Like,
public static class Validator
{
public static string IsValidate(string item)
{
// ...
}
}
Then, you can call it using:
Validator.IsValidate("String to validate")
EDIT: You could then check that your function is returning what you expect by doing:
if(Validator.IsValidate("String to validate") == "Expected result")
{
/* Logic to be executed here */
}
I have two constructors which feed values to readonly fields.
public class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt) => _intField = theInt;
public int IntProperty => _intField;
private readonly int _intField;
}
One constructor receives the values directly, and the other does some calculation and obtains the values, then sets the fields.
Now here's the catch:
I don't want to duplicate the
setting code. In this case, just one
field is set but of course there may
well be more than one.
To make the fields readonly, I need
to set them from the constructor, so
I can't "extract" the shared code to
a utility function.
I don't know how to call one
constructor from another.
Any ideas?
Like this:
public Sample(string str) : this(int.Parse(str)) { }
If what you want can't be achieved satisfactorily without having the initialization in its own method (e.g. because you want to do too much before the initialization code, or wrap it in a try-finally, or whatever) you can have any or all constructors pass the readonly variables by reference to an initialization routine, which will then be able to manipulate them at will.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Before the body of the constructor, use either:
: base (parameters)
: this (parameters)
Example:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
I am improving upon supercat's answer. I guess the following can also be done:
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
void setupStuff(ref int intField, int newValue)
{
//Do some stuff here based upon the necessary initialized variables.
intField = newValue;
}
public Sample(string theIntAsString, bool? doStuff = true)
{
//Initialization of some necessary variables.
//==========================================
int i = int.Parse(theIntAsString);
// ................
// .......................
//==========================================
if (!doStuff.HasValue || doStuff.Value == true)
setupStuff(ref _intField,i);
}
public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
{
setupStuff(ref _intField, theInt);
}
}
Here is an example that calls another constructor, then checks on the property it has set.
public SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Yeah, you can call other method before of the call base or this!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
When you inherit a class from a base class, you can invoke the base class constructor by instantiating the derived class
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Output of the sample program is
50 10 20
You can also use this keyword to invoke a constructor from another constructor
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
The output of this sample program is
20
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
public class Sample
{
public Sample(object inputToInt)
{
_intField = objectToInt(inputToInt);
}
public int IntProperty => _intField;
private readonly int _intField;
}
public static int objectToInt(object inputToInt)
{
switch (inputToInt)
{
case int inputInt:
return inputInt;
break;
case string inputString:
if (!int.TryParse(inputString, out int parsedInt))
{
throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}
Please, please, and pretty please do not try this at home, or work, or anywhere really.
This is a way solve to a very very specific problem, and I hope you will not have that.
I'm posting this since it is technically an answer, and another perspective to look at it.
I repeat, do not use it under any condition. Code is to run with LINQPad.
void Main()
{
(new A(1)).Dump();
(new B(2, -1)).Dump();
var b2 = new B(2, -1);
b2.Increment();
b2.Dump();
}
class A
{
public readonly int I = 0;
public A(int i)
{
I = i;
}
}
class B: A
{
public int J;
public B(int i, int j): base(i)
{
J = j;
}
public B(int i, bool wtf): base(i)
{
}
public void Increment()
{
int i = I + 1;
var t = typeof(B).BaseType;
var ctor = t.GetConstructors().First();
ctor.Invoke(this, new object[] { i });
}
}
Since constructor is a method, you can call it with reflection. Now you either think with portals, or visualize a picture of a can of worms. sorry about this.
In my case, I had a main constructor that used an OracleDataReader as an argument, but I wanted to use different query to create the instance:
I had this code:
public Subscriber(OracleDataReader contractReader)
{
this.contract = Convert.ToString(contractReader["contract"]);
this.customerGroup = Convert.ToString(contractReader["customerGroup"]);
this.subGroup = Convert.ToString(contractReader["customerSubGroup"]);
this.pricingPlan= Convert.ToString(contractReader["pricingPlan"]);
this.items = new Dictionary<string, Member>();
this.status = 0;
}
So I created the following constructor:
public Subscriber(string contract, string customerGroup) : this(getSubReader(contract, customerGroup))
{ }
and this method:
private static OracleDataReader getSubReader(string contract, string customerGroup)
{
cmdSubscriber.Parameters[":contract"].Value = contract + "%";
cmdSubscriber.Parameters[":customerGroup"].Value = customerGroup+ "%";
return cmdSubscriber.ExecuteReader();
}
notes: a statically defined cmdSubscriber is defined elsewhere in the code; My main constructor has been simplified for this illustration.
In case you need to run something before calling another constructor not after.
public class Sample
{
static int preprocess(string theIntAsString)
{
return preprocess(int.Parse(theIntAsString));
}
static int preprocess(int theIntNeedRounding)
{
return theIntNeedRounding/100;
}
public Sample(string theIntAsString)
{
_intField = preprocess(theIntAsString)
}
public Sample(int theIntNeedRounding)
{
_intField = preprocess(theIntNeedRounding)
}
public int IntProperty => _intField;
private readonly int _intField;
}
And ValueTuple can be very helpful if you need to set more than one field.
NOTE: most of the solutions above does not work for structs.
Unfortunately initializing struct fields in a method called by a constructor is not recognized by the compiler and will lead to 2 errors:
in the constructor: Field xxxx must be fully assigned...
in the method, if you have readonly fields: a read-only field cannot be assigned except in a constructor.
These can be really frustrating for example when you just need to do simple check to decide on which constructor to orient your call to.
How would you share the same object between two other objects? For instance, I'd like something in that flavor:
class A
{
private string foo_; // It could be any other class/struct too (Vector3, Matrix...)
public A (string shared)
{
this.foo_ = shared;
}
public void Bar()
{
this.foo_ = "changed";
}
}
...
// inside main
string str = "test";
A a = new A(str);
Console.WriteLine(str); // "test"
a.Bar();
Console.WriteLine(str); // I get "test" instead of "changed"... :(
Here, I don't want to give a ref to the Bar method. What I want to achieve is something that would look like that in C++:
class A
{
int* i;
public:
A(int* val);
};
A::A (int* val)
{
this->i = val;
}
I read there is some ref/out stuff, but I couldn't get what I'm asking here. I could only apply some changes in the methods scope where I was using ref/out arguments...
I also read we could use pointers, but is there no other way to do it?
This has nothing to do with sharing objects. You passed a reference to a string into the A constructor. That reference was copied into the private member foo_. Later, you called B(), which changed foo_ to "changed".
At no time did you modify str. str is a local variable in main. You never passed a reference to it.
If you had wanted to change str, you could have defined B as
public void Bar(ref string s)
{
this.foo_ = "changed";
s = this.foo_;
}
Consider:
public class C
{
public int Property {get;set;}
}
public class A
{
private C _c;
public A(C c){_c = c;}
public void ChangeC(int n) {_c.Property = n;}
}
public class B
{
private C _c;
public B(C c){_c = c;}
public void ChangeC(int n) {_c.Property = n;}
}
in main:
C myC = new C() {Property = 1;}
A myA = new A(myC);
B myB = new B(myC);
int i1 = myC.Property; // 1
myA.ChangeC(2);
int i2 = myC.Property; // 2
myB.ChangeC(3);
int i3 = myC.Property; // 3
Wrap your string inside a class. You need to do this because strings are immutable. Any attempt to change a string actually results in a new string.
class Foo {
class StringHolder {
public string Value { get; set; }
}
private StringHolder holder = new StringHolder();
public string Value {
get { return holder.Value; }
set { holder.Value = value; }
}
public Foo() { }
// this constructor creates a "linked" Foo
public Foo(Foo other) { this.holder = other.holder; }
}
// .. later ...
Foo a = new Foo { Value = "moose" };
Foo b = new Foo(a); // link b to a
b.Value = "elk";
// now a.Value also == "elk"
a.Value = "deer";
// now b.Value also == "deer"
I would split my answer to 2 parts:
1) If the variable is a reference type than it is already shared since you pass its reference to all interested objects. The only thing you should pay attention is that the reference type instances are mutable.
2) If the variable is a value type than you would have to use ref or out or some wrapper that is mutable and you can change the value inside the wrapper using a method or a property.
Hope that helps.
You need to pass the paramter as a reference to your method,
class A
{
private string foo_; // It could be any other class/struct too (Vector3, Matrix...)
public A(string shared)
{
this.foo_ = shared;
}
public void Bar(ref string myString)
{
myString = "changed";
}
}
static void Main()
{
string str = "test";
A a = new A(str);
Console.WriteLine(str); // "test"
a.Bar(ref str);
Console.WriteLine(str);
}
When a variable is a string, it is a reference.
Try to clone the string. http://msdn.microsoft.com/en-us/library/system.string.clone.aspx