Passing a multi-method object to another class - c#

As part of a personal project I am working on I took a small codebase written by another programmer and was trying to refactor it to my own purposes. Long story short, they had this huge section of code that was an incoming command parser. I moved the code to it's own class file and moved several code bits to their own methods in that class. The problem I'm encountering is that I can't pass two needed objects from the original block of code to the new parser class. The orginal code section uses an mutliple-method object called AllSockets. I can't seem to figure out how to pass this object to the new class method without getting the error
Error 2 Argument 2: cannot convert from 'method group' to 'object'
The invoking line of code:
bool wasValidCommand = (commandParser.CheckForCommands(thisConnection, AllSockets, characterPath, helpFilePath));
The method invoked:
public bool CheckForCommands(ConnectionInfo _connected, object _AllSockets, string characterPath, string helpFilePath)
I've posted the hosting Server.cs class here: http://codepad.org/1kRHA1nk
The new class I am trying to pass the object to is here: http://codepad.org/oONRaEtt
Warning: The code is really hacked together right now and variable naming is a nightmare. I can paste the specific sections if that would be easier to read. Any help would be appreciated.

The AllSocket method is declared as
public object AllSockets(string tempFlag, object objectOne, object object_Two, object object_Three)
From a quick look over the code, it appears AllSockets is used in the private Shout(..) method of the class - as method. So in order to pass this as a function object, you may declare the CheckForCommands method with a parameter of type delegate or Function:
delegate object AllSocketDelegate (string tempFlag, object objectOne, object object_Two, object object_Three);
public bool CheckForCommands(ConnectionInfo _connected, AllSocketDelegate _AllSockets, string characterPath, string helpFilePath)
or similar with the Func instead of a delegate.

Replace object _AllSockets with:
Func<string, object, object, object, object>_AllSockets
You should probably replace this in CheckForCommands, Shout and Tell method signatures.

AllSockets is a method. I'm guessing you want to take the object that the AllSockets method returns and pass that into the commandParser.CheckForCommands function.
Try something like:
object allSockets = AllSockets(...);
bool wasValidCommand = (commandParser.CheckForCommands(thisConnection, allSockets, characterPath, helpFilePath));

Related

Is casting string or reference type create another object in memory?

Today I am reading article and article shows the code snippet:-
string s1 = "Something";
string s2 = (string)s1.Clone();
if ((object).ReferenceEquals(s1, s2))
throw new Exception("But I need to know!");
Code snippet throws an error why? I can't understand what happened under a hood in CLR.
My question is a string or reference type casting create a new object or not?
From this MSDN Link, It specifically states The return value is not an independent copy of this instance; it is simply another view of the same data.
and that there is little reason to call it directly.
So, in short the Clone() method does not create a new copy. Type casting does not influence the instance of the data in memory, it merely provides another way of interpreting the same data.
The correct way to call a static method is to directly call that method on the type. class.Method(). By wrapping the type in parenthesis the compile considers this a cast of an instance.
Change this line ...
if ((object).ReferenceEquals(s1, s2))
... to this ...
if (object.ReferenceEquals(s1, s2))

Pass the signature of a method and invoke it on another object of the same type

I want to pass a method around and store it. Let's say the method takes one int and returns void. I'd wrap it in Action< int >.
Now, is there a way to invoke that method but not on the object it originated from but a different instance of the same class?
It's kind of hard to be more specific than that but please ask if anything is confusing and I'll try again.
Now, is there a way to invoke that method but not on the object it originated from but a different instance of the same class?
EDIT: Okay, ignore my first attempt. I thought you were talking about a different class.
It sounds like you should actually be wrapping the method in an Action<object, int> (or a more strongly typed version).
Alternatively, you could create a new delegate using:
Action<int> newAction = (Action<int>) Delegate.CreateDelegate(typeof(Action<int>),
newTarget,
oldAction.Method);
You can use the Type.GetMethod overload which takes parameter types. This allows you to get the exact method with the specified parametere types.

Can C# Delegates work this way?

I'm trying to use delegates to cut down on my code in this project.
I have 4 DropDownLists in my asp.net page. In my codebehind file I'm binding them to different business object calls with data. Right now I have the following code:
DeptList.DataSource = bl.getAcademicDepts();
DeptList.DataBind();
TermList.DataSource = bl.getTerms();
TermList.DataBind();
InstructorList.DataSource = bl.getInstructors();
InstructorList.DataBind();
EEList.DataSource = bl.getEE();
EEList.DataBind();
This seems really repetitive so I decided to make a function as a shortcut
private void SourceAndBind(DropDownList d, <business layer method call>)
{
d.DataSource = <businesslayer method call>();
d.DataBind();
}
Then my first block of code simply becomes
SourceAndBind(DeptList, bl.getAcademicDepts());
SourceAndBind(TermList, bl.getTerms());
SourceAndBind(InstructorList, bl.getInstructors());
SourceAndBind(EEList, bl.getEE());
However, I don't know what to put for the second parameter. Each one of the business layer calls takes no parameters, but they each return objects of different types. I tried using delegates but I couldn't figure out how to create one without a defined return type or no parameters. Is it possible to achieve what I want with c#? I know that works in python which is where I'm coming from.
You don't need delegates to do this. Just declare the second parameter as object.
// Takes drop down list and data to assign to 'data source'
private void SourceAndBind(DropDownList d, object data) {
d.DataSource = data;
d.DataBind();
}
// Call methods from bussiness layer and bind results
SourceAndBind(DeptList, bl.getAcademicDepts());
SourceAndBind(TermList, bl.getTerms());
SourceAndBind(InstructorList, bl.getInstructors());
SourceAndBind(EEList, bl.getEE());
You could use delegates too. However, since you're only calling the method once, you can call the bussiness layer method to get the data and then pass the result to SourceAndBind. (Delegates would be useful for example if you wanted to choose one of several ways of loading the data, or if you wanted to delay loading until some later point).
Well, Func<object> would be a very general way of doing that. That's "a function with no parameters that returns an object". Any parameterless function returning a reference type should be convertible to that delegate type. However, your "usage" code wouldn't be quite right as it. It would be:
SourceAndBind(DeptList, bl.getAcademicDepts);
SourceAndBind(TermList, bl.getTerms);
SourceAndBind(InstructorList, bl.getInstructors);
SourceAndBind(EEList, bl.getEE);
Note the lack of brackets, which means these are method groups rather than method calls. (To follow .NET naming conventions I'd suggest renaming your methods to start with capital letters, btw.)
That's appropriate if you only want to call the method conditionally. As Tomas says though, you don't need to use delegates here. If you're happy for SourceAndBind to only get called after you've called the method, you can definitely just perform the method call in the argument and pass the result as object.
private void SourceAndBind(DropDownList d, Func<IEnumerable<object>> businessLayerMethod)
{
d.DataSource = businessLayerMethod();
d.DataBind();
}
IEnumerable<object> where object is your datatype.

C# delegate to Java conversion

I am in the process of converting some code from C# to Java. I have never used C# before, but it has been pretty easy up to this point.
I have a line that looks like this in the C# file:
coverage.createMethod = delegate (Gridpoint gp){
//Some method stuff in here, with a return objecct
}
What exactly is this trying to do? It seems a little bit like an inline class but I am not sure how to go about converting htis to java
Edit: more on the specific problem
In a file called STKDriver.java i have the following
CoverageDefinitionOnCentralBody coverage = new CoverageDefinitionOnCentralBody(...);
.
.
.
DClass value = new DClass(STKDriver.class, "invoke", CoverageGrid.class);
coverage.setGridPointCreationMethod(value);
In the fill DClass.java, which extends CreateCoverageGridPointForAccess I have the following:
public DClass(Class class1, String string, Class<CoverageGridPoint> class2{}
.
.
.
public IServiceProvider invoke(CoverageGridPoint gridPoint){
return something; //of the classtype Platform
}
Is this done correctly? The class definitions are linked here:
http://www.agi.com/resources/help/online/AGIComponentsJava/index.html?page=source%2FWhatsNewJava.html
Notice that the class CreateCoverageGridPointForAccess is abstract and extends that Delegate class.
Does this implementation I have created look correct? I Can write in more code if necessary
This is an anonymous method in C#. It's technically the same thing as:
coverage.createMethod = new Func<Gridpoint, object>(SampleMethod);
public object SampleMethod(Gridpoint gp)
{
return thingy; // Pseudo for return value
}
It's just a shortcut you can use to code less.
Tejs' answer is correct. However be careful because anonymous functions can use closures which means using an existing local variable declared in the outer function, from the anonymous delegate. I'm no Java programmer so I don't know if Java supports this.
coverage.createMethod is a Delegate.
The following code creates an anonymous method and assigns it to the delegate:
coverage.createMethod = delegate (Gridpoint gb) {
}
so that when somebody calls coverage.createMethod, your anonymous method gets executed.

Using "this" - many instances of class, calling private method

I have a server where every connected client is represented by an instance of client class. This class is responsible for data processing. I always thought that when calling private function even when there are more instances of the same class, I dont need to use "this" keyword because its considered as local call, also:
if (data[1]==2 && data [3]==2)
SendAck();
But when there were more players (more client classes), sometimes the message was sent to another player and the same with other methods. All was OK when I added "this" to all methods call. Is it possible that wihout "this" it calls method from some other class?
Thanks!
EDITL: What about using public members like public dictionary in each instance and then not using this keyword /like when calling TryGetValue/?
No, this isn't possible. "this" is almost all of the time optional. A situation where you would need it would be if you have a method (for example your constructor) that takes parameters of the same name than fields of your class and you want to assign the values of these parameters to the fields, eg:
class Test
{
private string strValue;
public Test(string strValue)
{
this.strValue = strValue;
}
}
I thinks there is another problem in your code. Could you please give more details?
There isn't any difference between SendAck(); and this.SendAck();, if the method is a member of your class. You will always call the method from the instance that is calling the method.
Check what the method actually does when called, using the debugger. You will see that it is the same method, with or without the this keyword.
From C# Specification:
7.5.7 This access
…
When this is used in a primary-expression within an
instance method or instance accessor
of a class, it is classified as a
value. The type of the value is the
instance type (§10.3.1) of the class
within which the usage occurs, and
the value is a reference to the object
for which the method or accessor was
invoked.
I suspect that you have problems with multithreaded access to instances of type that represent connected clients.

Categories