Converting vb web project to c# using vwd express 2010.
Development system is a 64bit windows 7.
I have a commonly used function declared in an external cs file.
Contents of file "clsCommon.cs" =
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;
namespace Project_Website
{
public class clsCommon
{
public void testA()
{
}
} // clsCommon
} // namespace
In code behind I try to access the function testA() as follows:
testA();
Also tried:
clsCommon.testA();
and
Project_Website.clsCommon.testA();
The actual example I want to use is more complicated, but this is the simplest example that manifests the problem(s) I enumerate below:
The As I type, Intellisense recognizes clsCommon, but doesn't think testA() is a method in it. Intellisense only sees two methods: Equals() and ReferenceEquals().
I ignore Intellisense and compile anyway, which produces the following error message:
Error 1 An object reference is required for the non-static field, method, or property 'Project_Website.clsCommon.testA()'
What is the root cause of this problem?
You either need to make that method static, or create an instance of the class clsCommon to use it, i.e.:
public class clsCommon
{
public static void testA()
{
}
} // clsCommon
Note that above method signature screams "side effects" since you don't return anything and are not passing anything in. If you are modifying other members or properties of the class, you should create an instance instead and use a member method:
var common = new clsCommon();
common.testA();
You should only make the method static if you do not need access to any other properties or methods with the clsCommon class. If that is the case for all of your methods, and clsCommon is just holding a bunch of utility methods, you should make the clsCommon class static as well.
Related
I'm pretty new to c#, and I'm using Harmony patches to make a mod for a video game. The method I'm trying to patch is a private method which takes an internal class instance as a parameter. I've been able to use reflection to handle private methods in a few other patches, but when I try to add the internal parameter, I get a build error saying the class is inaccessible due to it's protection level.
I was trying to use the solution from this question, but I think I'm having some scope issues. Right now, I have something like
using System;
...
using System.Reflection;
using HarmonyLib;
using namespacesFromGame; // Including namespace where the internal is declared
...
namespace MyMod
{
[HarmonyPatch(typeof(GameClass))]
class MyPatch
{
Type MyInternal = typeof(GameClass).Assembly.GetType("GameInternal");
public static bool MethodPatch(GameClass__instance,..., MyInternal myInternal, ...)
{
...
}
}
}
When I try to do this, it tells me The type or namespace name 'MyInternal' cannot be found.
Where should I be putting my MyInternal declaration so it can be used as a parameter to MethodPatch, and so I will also be able to use the myInternal instance in the patch?
In C# you cannot declare the type of a property with another variable.
I see two solutions to this problem.
You can either do this :
using System;
...
using HarmonyLib;
using namespacesFromGame; // Including namespace where the internal is
namespace MyMod
{
[HarmonyPatch(typeof(GameClass))]
class MyPatch
{
public static bool MethodPatch(GameClass __instance,..., object myInternal, ...)
{
...
// do reflexion to access the method, the field and prop the object
}
}
}
This should work; but if you are new to C# the reflection may not necessarily be the easiest thing to do and it can quickly make your code unreadable.
Or do this :
You can publicise (make public) the dll you want to use. If you do this, you will have access to all classes, methods and ect... By doing this you will only have to use the desired type. But, you will have to compile your code in unstable.
For publicise, i found two github repo :
https://github.com/rwmt/Publicise
https://github.com/iRebbok/APublicizer
(you can also create your own but I think that to start it would be better to take one already made)
It will require republishing the assembly each time there is an update if your mod is outdated.
I also create modes on unity games. This is the solution I use and some FrameWork for modding uses to.
I don't know if there are performance impacts of using unstable code and calling private methods.
I advise you this solution, you would get cleaner code and you will have access to code more easily. But that is my personal opinion.
I am working on an issue I do not remember ever having before.
I am using VS2012 C#
When i add using System.IO; to my main program everything works fine, however when I add it to my class file it will not let me use all of the methods.
using System;
using System.Collections.Generic;
using System.IO;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FoxySearch
{
class FoxySearch
{
File. <<<<----- here i want to add File.Exists("Blablalba")
}
}
For some reason it wont let me add it. As soon as I add the period the intellisense closes and shows no options.When I then type it out myself it shows red and says,
System.IO.File.Exists(string) is a method but is used like a type
You haven't really given enough code to say for sure, but it sounds like you're probably trying to write "normal code" directly in a class declaration, instead of in a method or property declaration.
Classes can only include declarations - method declarations, field declarations etc. You can't write:
class Foo
{
int i = 10;
Console.WriteLine(i);
}
etc. The first line is valid as it's a variable declaration - the second isn't, as it's just a method call. If you move the code into a method, then it's fine:
class Foo
{
public void Bar()
{
int i = 10;
Console.WriteLine(i);
}
}
Additionally, I'd suggest that you revisit your naming - using the same name for a class and a namespace is a bad idea.
You need to put it inside a function or sub, property and so forth.
You need to put the code in a method, for example:
class FoxySearch
{
public bool DoesFileExist(string filePath)
{
return File.Exists(filePath);
}
}
u have written in class, u cant write there. & also file.Exists() returns boolean value. u have to write something like this:
boolean a= File.Exists("bla");
You use File.Exists() in class not in method it is a problem.
You must add Reference to assembly in your project.
I want to be able organize my most common code elements so that they can be "included" with a using statement similar to
using System;
using System.IO;
I am able to do this to a certain extent, but because of C# rules about namespaces and classes, I am unable to access my stuff directly, I always have to add it to a class and then access it by .item.
For example if I make a C# file named MyStuff.cs as follows:
namespace MyStuff
{
public static class MyClass
{
public static int MyCode(...)
{
...
}
}
}
I have to use it in my other code like this:
using MyStuff
...
int result = MyClass.MyCode(...);
...
I would like to be able to just access it like this (without the MyClass):
using MyStuff
...
int result = MyCode(...);
...
But I can't get that to work. I read somewhere that adding the "static" to the class they are in then the dot notation would not be needed, but that does not appear to be true.
Can anybody explain how to do this, or am I stuck with the extra layer?
Thanks!
I don't think it can be done.
In order to something to be accessed directly from within a namespace, it has to be an object. Functions cannot be directly put inside a namespace.
You can achieve what you want by making use of extension method by writing an extension method for instances of the 'Object' class (which is more of a hack). But you will still have to invoke it this way, this.MyCode().
Another solution is to have a superclass where you have this function MyCode() and inherit the place where you are going to use MyCode() from there but I am pretty sure that you have already considered something which is as basic as that.
Reading and messing around to understand static classes and static methods and their differences with non static methods and their usage which i still don't get except maybe for the Main method which must not be made an instance(object) of a class.
Why if i try to use:
using static System.ApplicationId;
public class Program
{
static void Main()
{
Copy(SOMETHING)// Copy method doesn't exist
}
}
Then try to use a method from ApplicationId like Copy();
The IDE? can't find the method?
Doing the same with:
using static System.Console;
public class Program
{
static void Main()
{
Writeline("Hello"); // OK
}
}
Then try to find a method from Console like WriteLine();
It can find it and i can use it.
Why does that happen?
My understanding is That those are both static members? Isn't that the reason why i cant make instances of those 2 classes? Yet i can use the methods in the second example but not in the first one since it seems that it doesn't let me (error: copy() doesn't exist in the current context...).
The short answer is that you wouldn't use the static keyword in a using statement for non-static namespaces like System.ApplicationId
To use methods on a non-static (instance) class, you have to first make an instance of it using new. The tl;dr part followsTo avoid having to write out the namespace prefix System. every time you want to refer to ApplicationId, you can add
using System;
and then in the class, you can get to the someMethod() method with:
new ApplicationId().someMethod();
Now let's talk about static:
Before C# version 6, you just couldn't use a using statement on a static class, so to get access to a static method like
System.Console.WriteLine()
you'd first add the non-static parent (System) with
using System
and then refer to the static method using the namespace
Console.WriteLine
With the using static syntax, you add the 'Console.' part of the namespace once per class on the using statement like so:
`using static System.Console;`
and then you can use WriteLine() instead of Console.WriteLine. I have to guess that the WriteLine() method has got to be the most common use case for this functionality.
If you check out https://msdn.microsoft.com/en-us/library/system.console%28v=vs.110%29.aspx it shows that System.Console is a static class, so using static is appropriate there.
However, System.ApplicationId is non-static (see https://msdn.microsoft.com/en-us/library/system.applicationid%28v=vs.110%29.aspx) so you can't use using static.
The answer is simple, the methods in ApplicationId are not marked as static.
Let's see the difference between static and instance methods:
Static method:
Console.WriteLine();
******* *********
^ ^
class method
name name
Instance methods:
Random aRandomObject = new Random();
aRandomObject.Next();
************* ****
^ ^
name of an method
instance of name
Random
As you can see here, you need an instance of that class in order to use non-static methods. But for static methods, you don't need an instance.
The using static directive allows you to omit the class name when you call a static method.
"But why doesn't it allow us to call instance methods like this?" you asked. As I have said above, you need an instance to call instance methods. If you only write the method name to call the method, how can the compiler know what instance do you want to call it on?
ApplocationId is not a static class, so you need to create an instance of it.
I'm trying add the ability to lookup elements in a List<KeyValuePair<string,int>> by overriding the indexer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class MyList : List<KeyValuePair<string, int>>
{
public int this[string key]
{
get
{
return base.Single(item => item.Key == key).Value;
}
}
}
}
For some reason, the compiler is throwing this error:
'System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string,int>>' does not contain a definition for 'Single'.
While it is true that List<T> doesn't have that method, it should be visible because it is an extension method from the System.Linq namespace (which is included). Obviously using this.Single resolves the issue, but why is access via base an error?
Section 7.6.8 of the C# spec says
When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct.
Which might seem to preclude access to extension method via base. However it also says
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
If base.I is just like ((B)this).I then it seems like extension methods should be allowed here.
Can anyone explain the apparent contradiction in these two statements?
Consider this situation:
public class Base
{
public void BaseMethod()
{
}
}
public class Sub : Base
{
public void SubMethod()
{
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base) { }
}
Here are some interesting assertions about this code:
I cannot call the extension method using ExtensionMethod() from neither Base nor Sub.
I cannot call base.ExtensionMethod() from Sub.
I can call the extension method using Extensions.ExtensionMethod(this) from both Sub and Base.
I can call the extension method using this.ExtensionMethod() from both Sub and Base.
Why is this?
I don't have a conclusive answer, partly because there might not be one: as you can read in this thread, you have to add this. if you want to call it in the extension method style.
When you're trying to use an extension method from the type it is in (or - consequently - from a type that is derived from the type used in the extension method), the compiler doesn't realize this and will try to call it as a static method without any arguments.
As the answer states: they [the language designers] felt it was not an important use case scenario to support implicit extension methods (to give the beast a name) from within the type because it would encourage extension methods that really should be instance methods and it was considered plain unnecessary.
Now, it is hard to find out what is happening exactly under the covers but from some playing around we can deduce that base.X() does not help us. I can only assume that base.X performs its virtual call as X() and not this.X() from the context of the baseclass.
What do I do when I want to call the extension method of a baseclass from a subclass?
Frankly, I haven't found any truly elegant solution. Consider this scenario:
public class Base
{
protected void BaseMethod()
{
this.ExtensionMethod();
}
}
public class Sub : Base
{
public void SubMethod()
{
// What comes here?
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base)
{
Console.WriteLine ("base");
}
public static void ExtensionMethod(this Sub sub)
{
Console.WriteLine ("sub");
}
}
There are 3 ways (leaving aside reflection) to call the ExtensionMethod(Base) overload:
Calling BaseMethod() which forms a proxy between the subclass and the extensionmethod.
You can use BaseMethod(), base.BaseMethod() and this.BaseMethod() for this since now you're just dealing with a normal instance method which in its turn will invoke the extension method. This is a fairly okay solution since you're not polluting the public API but you also have to provide a separate method to do something that should have been accessible in the context in the first place.
Using the extension method as a static method
You can also use the primitive way of writing an extension method by skipping the syntactic sugar and going straight to what it will be compiled as. Now you can pass in a parameter so the compiler doesn't get all confused. Obviously we'll pass a casted version of the current instance so we're targetting the correct overload:
Extensions.ExtensionMethod((Base) this);
Use the - what should be identical translation - of base.ExtensionMethod()
This is inspired by #Mike z's remark about the language spec which says the following:
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
The spec literally says that base.I will be invoked as ((B) this).I. However in our situation, base.ExtensionMethod(); will throw a compilation error while ((Base) this).ExtensionMethod(); will work perfectly.
It looks like something is wrong either in the documentation or in the compiler but that conclusion should be drawn by someone with deeper knowledge in the matter (paging Dr. Lippert).
Isn't this confusing?
Yes, I would say it is. It kind of feels like a black hole within the C# spec: practically everything works flawlessly but then suddenly you have to jump through some hoops because the compiler doesn't know to inject the current instance in the method call in this scenario.
In fact, intellisense is confused about this situation as well:
We have already determined that that call can never work, yet intellisense believes it might. Also notice how it adds "using PortableClassLibrary" behind the name, indicating that a using directive will be added. This is impossible because the current namespace is in fact PortableClassLibrary. But of course when you actually add that method call:
and everything doesn't work as expected.
Perhaps a conclusion?
The main conclusion is simple: it would have been nice if this niche usage of extension methods would be supported. The main argument for not implementing it was because it would encourage people to write extension methods instead of instance methods.
The obvious problem here is of course that you might not always have access to the base class which makes extension methods a must but by the current implementation it is not possible.
Or, as we've seen, not possibly with the cute syntax.
Try to cast the instance to its base class:
((BaseClass)this).ExtensionMethod()
Applied to your code:
public class Base
{
public void BaseMethod()
{
}
}
public static class BaseExtensions
{
public static void ExtensionMethod(this Base baseObj) { }
}
public class Sub : Base
{
public void SubMethod()
{
( (Base) this).ExtensionMethod();
}
}