I want to use a dependency that I downloaded in the class scope. This code works:
using System;
using System.IO;
using System.Collections;
namespace PrintFilesToConsole
{
class Preprogram
{
public void Main2()
{
IEnumerable myDirs = System.IO.Directory.EnumerateDirectories("/Users/Eunice/Desktop");
Console.WriteLine("Hello World!");
}
}
class Program
{
static void Main(string[] args)
{
Preprogram preprogram = new Preprogram();
preprogram.Main2();
}
}
}
but when I write
System.IO.Directory.EnumerateDirectories
("/Users/Eunice/Desktop");
outside of the function called
Main2
, into the scope of the class
Preprogram
, the computer says that the function doesn't exist in the current context
unless I assign the return value to a variable, as in
IEnumerable myDirs = System.IO.Directory.EnumerateDirectories("/Users/Eunice/Desktop");
enter code here
Let's simplify your example to demonstrate where the problem lies.
We have the class A which contains the method DoSomething.
public class A
{
public int DoSomething()
{
return 42;
}
}
lets say it also contains the method MakeStuff, which calls the DoStuff method:
public class A
{
public int DoSomething()
{
return 42;
}
public void MakeStuff()
{
int x = this.DoSomething();
// We called the method DoSomething, which returns 42, and now x equals 42.
}
}
what we did in MakeStuff is we called a method and assigned the return value to a local variable.
We could also put a field (or property) in the class A:
public class A
{
private int y;
...
}
and we can even assign a default value to that field:
public class A
{
private int y = 10;
...
}
but the value doesn't have to be hardcoded: we can also use the return value of a function, just as we did in the MakeStuff method when we assigned the return value to a local variable:
public class A
{
private int y = this.DoSomething();
// Now y equals 42, because DoSomething() returns 42.
...
}
but we cannot call a function outside of a method if we discard the return value, e.g. we cannot do this:
public class A
{
this.DoSomething();
// This will not compile!
}
I hope this simple example shows why you get the described error. I tried to keep it as simple as possible - yet if you don't understand parts of the answer or anything, please feel free to comment where you need help with and I will do my best to help you.
Related
This question already has answers here:
How to call an appropriate method by string value from collection?
(3 answers)
Closed 3 years ago.
I have 1000 methods called method0001, method0002 , ... ,method1000.
I have a variable that takes values between 1 and 1000.
If the value of the variable is x, I'd like to call methodx. For instance, if the value of the variable is 34, I'd like to call method0034. How can I code this in C# please?
Many people are asking what is need for Methodwxyz. Every method is a different type of math question.
i've done this, following the helpful comments but am getting errors (edited the question from earlier)
using System.Collections.Generic;
using UnityEngine;
public class TextControl : MonoBehaviour
{
public static TextControl instance;
void Start()
{
instance = this;
}
// Update is called once per frame
void Update()
{
this.GetType().GetMethod("Template00" + "1").Invoke(this, null);
}
public static string Templates001()
{
// doing something here
}
}
thanks
You could do this through reflection. Edit for a quick sample (forgot invoke parameters). Some tips about reflection:
If you get a nullexception that means it can't find the method
The method you are invoking needs to be public
If you use obfuscation you may not have the same names for the method
Code
public class Program
{
public static void Main(string[] args)
{
Check method1 = new Check(1);
Check method2 = new Check(2);
}
}
public class Check
{
public Check(int x)
{
this.GetType().GetMethod("Method" + x).Invoke(this, null);
}
public void Method1()
{
Console.WriteLine("Method 1");
}
public void Method2()
{
Console.WriteLine("Method 2");
}
}
I have an object that can be of type AudioRequest or VideoRequest. Both classes inherit from Request. I have this class:
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
I want to be able to call DoThings.HandleRequest(r) where r can be either a VideoRequest or AudioRequest and have it call the correct one. Is that possible? I have no control over the *Request classes, so I can't do anything to them. I do have control of the DoThings class and the code that calls HandleRequest. This is the code that calls it, it is WebAPI:
public Response Post(Request input)
{
return DoThings.HandleRequest(input);
}
The code above gives the error Argument 1: cannot convert from 'Request' to 'AudioRequest'.
The original code that I was cleaning up had this:
if (input.GetType() == typeof(AudioRequest))
{
var audioRequest = (AudioRequest)input;
DoThings.HandleRequest(audioRequest);
}
else if (input.GetType() == typeof(VideoRequest))
{
var videoRequest = (VideoRequest)input;
DoThings.HandleRequest(videoRequest);
}
But I figured there was a cleaner way to do this.
Based on the information you've provided so far, your question appears to be a duplicate of How to call a function dynamically based on an object type. I agree with the answer, that the fact that you want to do this suggests you should rethink the design. But, you can use dynamic to accomplish what you want.
Here's a simple console program that demonstrates the basic idea:
class Program
{
static void Main(string[] args)
{
A b = new B(), c = new C();
M(b);
M(c);
}
static void M(A a)
{
WriteLine("M(A)");
M((dynamic)a);
}
static void M(B b)
{
WriteLine("M(B)");
}
static void M(C c)
{
WriteLine("M(C)");
}
}
class A { }
class B : A { }
class C : A { }
The output is:
M(A)
M(B)
M(A)
M(C)
As you can see, in each case the M(A) method is called first, and then the appropriate M(B) or M(C) overload is called from M(A).
In your own example, this could look something like this:
public static DoThings
{
public static void HandleRequest(Request r)
{
// Dynamic dispatch to actual method:
HandleRequest((dynamic)r);
}
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
Note that dynamic does incur a run-time cost, particularly the first time a method is called with a given run-time type. But depending on the frequency and complexity of these "requests", using dynamic could be the cleanest way out of the current situation.
C# will call the appropriate function that matches the arguments and their types.
That being said, both of your functions accept AudioRequest, I believe one of those should accept a VideoRequest.
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
If for some reason you must have two different functions that take only AudioRequest you can differentiate between two function with an extra parameter
public static class DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(AudioRequest r, bool UseAlternativeMethod)
{
// Do other things.
}
}
Simply having a second parameter will call the second method regardless of it's value.
This isn't a best practices solution as you'd rather discriminate between them by accurately renaming the method name to be accurate but in practice you don't always have a choice.
I am writing a testing framework for my system, which allows users to create mocked inputs to the system. The system manipulates that input, and updates some of its members for later post processing.
In order to allow users to mock the input, I need to be able to update a mocked input's members. Furthermore, the input may not be a mock, so I would prefer a solution oblivious to the type of element received.
Simply put, I have a function which receives an object and attempts to set one of its properties:
func(object a)
a.m = 5;
Which I want to test by mocking its input a, using the Moq library. Unfortunately, my test failed, since mocked objects' members need to be set using Mock.SetUpGet, instead of standard member assignment.
What would be a good way to test such a function, without changing it?
In order to be able to mock and test it, the property must be virtual, but if that's the case you can use the SetupSet method, rather than SetupGet:
public class A
{
public virtual int m { get; set; }
}
[TestFixture]
public class Tests
{
public static void SetProperty(A a)
{
a.m = 5;
}
[Test]
public void IsThePropertySet()
{
var x = new Mock<A>();
x.SetupSet<int>(a => a.m = 5).Verifiable();
SetProperty(x.Object);
x.Verify();
}
}
Your function should have getters and setters anyway.
And a good way of testing whether your functions work is to do a small-scale test. Initialize an object and send that in to your method, seeing whether it does what you want.
public class myClass
{
public int number;
public void setNumber(int nNum)
{
number = nNum;
}
public int getNumber()
{
return number;
}
}
class Program
{
static void myMethod(myClass obj, int nNumb)
{
//obj.setNumber(nNumb);
obj.number = nNumb;
}
static void Main(string[] args)
{
myClass myObj = new myClass();
myMethod(myObj, 3);
//Console.WriteLine(myObj.getNumber());
Console.WriteLine(myObj.number);
Console.ReadLine();
}
}
}
Output: 3
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.
I've this question about pass some instances by ref or not: here is my problem:
Case 1: simple var like int:
private void button2_Click(object sender, EventArgs e)
{
int nTest = 10;
testInt(nTest);
MessageBox.Show(nTest.ToString());
// this message show me 10
testIntRef(ref nTest);
MessageBox.Show(nTest.ToString());
// this message show me 11
}
private void testInt(int nn)
{
nn++;
}
private void testIntRef(ref int nn)
{
nn++;
}
this is exactly what I think, if I use the ref, the parameter is passed by reference, so if is changed, when I exit from the function, the value is changed...
Case 2: class:
// simple class to understand the reference..
public class cTest
{
int nTest;
public cTest()
{
setTest(0);
}
public void setTest(int n)
{
nTest = n;
}
public int getTest()
{
return nTest;
}
}
// my main code
private void button3_Click(object sender, EventArgs e)
{
cTest tt = new cTest();
tt.setTest(2);
testClass(tt);
// I expect that the message shows me 2, 'cause testClass
// doesn't have (ref cTest test)
MessageBox.Show(tt.getTest().ToString());
}
private void testClass(cTest test)
{
test.setTest(55);
}
and, as written in the comment on the code, I don't have passed my cTest as reference, but the result is the same, the message show me 55 and not 2..
How can I pass a class without reference?
How can I pass a class without reference?
You can't.
You can clone that instance and send it, but it will still be sent by ref...
class - Reference type
struct - Value type.
Reading:
Article about passing variables in C#
Wikipedia about Objects copy- shallow copy + deep copy.
Quoting Jon Skeet C# in depth second edition:
MYTH #3: “OBJECTS ARE PASSED BY REFERENCE IN C# BY DEFAULT”
This is probably the most widely propagated myth. Again, the people who make this
claim often (though not always) know how C# actually behaves, but they don’t know
what “pass by reference” really means. Unfortunately, this is confusing for people who
do know what it means. The formal definition of pass by reference is relatively complicated,
involving l-values and similar computer science terminology, but the important
thing is that if you pass a variable by reference, the method you’re calling can change
the value of the caller’s variable by changing its parameter value. Now remember that the
value of a reference type variable is the reference, not the object itself. You can change
the contents of the object that a parameter refers to without the parameter itself being
passed by reference.
For instance, the following method changes the contents of the
StringBuilder object in question, but the caller’s expression will still refer to the
same object as before:
void AppendHello(StringBuilder builder)
{
builder.Append("hello");
}
When this method is called, the parameter value (a reference to a StringBuilder) is
passed by value. If I were to change the value of the builder variable within the
method—for example, with the statement builder = null;—that change wouldn’t be
seen by the caller, contrary to the myth.
C# in depth Value types and reference types page 46
If you want something like that, you want to use struts instead of classes.
If you just want to make sure that a method can't modify an argument, then you can create a read-only base class:
public abstract class ReadOnlyUser
{
public string GetName() { ... }
}
public class User : ReadOnlyUser
{
public void SetName(string name) { ... }
}
Then you can write the method in such a way that the method body can't modify the argument by mistake:
public void Register(ReadOnlyUser user)
{
string name = user.GetName();
user.SetName("John"); // doesn't compile
}
Of course you can invoke this method with an instance of the User class:
var user = new User(...);
Register(user);
You can also implement a read-only interface:
public interface IReadOnlyUser
{
string GetName();
}
public interface IUser : IReadOnlyUser
{
void SetName(string name);
}
public class User : IUser
{
public string GetName() { ... }
public void SetName(string name) { ... }
}
public void Register(IReadOnlyUser user)
{
string name = user.GetName();
user.SetName("John"); // doesn't compile
}