Is it possible to add a method to a class from another project?
I have a class:
namespace ProjectLibrary
{
public class ClassA
{
// some methods
}
}
I want to add a method to save my object in a file, but I don't want to add this method in my project ProjectLibrary because I don't want to add reference to System.IO (I want to use this project for android application and PC application).
Is there a possibility to add a method SaveToFile() usable only in another project? Or create an abstract method in ClassA but define it in other project.
Like this :
using ProjectLibrary;
namespace ProjectOnPC
{
void methodExample()
{
ClassA obj = new ClassA();
// do something
obj.SaveToFile();// => available only in namespace ProjectOnPC
}
}
Thank you for help
You can use extension methods.
Example:
namespace ProjectOnPC
{
public static void SaveToFile(this Class myClass)
{
//Save to file.
}
}
The thing You are looking for is called Extension method:
DotNetPerls
MSDN link
What are Extension Methods?
Code for base class:
namespace ProjectLibrary
{
public ClassA
{
// some methods
}
}
Extension method:
using ProjectLibrary;
namespace ProjectOnPC
{
void SaveToFile(this ClassA Obj, string Path)
{
//Implementation of saving Obj to Path
}
}
Calling in Your program:
using ProjectLibrary;
using ProjectOnPc; //if You won't include this, You cannot use ext. method
public void Main(string[] args)
{
ClassA mObj = new ClassA();
mObj.SaveToFile("c:\\MyFile.xml");
}
You can create an extension method for this purpose.
Here's an example.
In your ProjectOnPc namespace create a class like this:
public static class ClassAExtension
{
public static void SaveToFile(this ClassA obj)
{
// write your saving logic here.
// obj will represent your current instance of ClassA on which you're invoking the method.
SaveObject(obj).
}
}
You can learn more about extension methods here:
https://msdn.microsoft.com/en-us//library/bb383977.aspx
Related
I want to call a static void function from another class, but it's said
The name [funcion name here] does not exist in the current context
Each class is in the same project, Framework 4.5.2
Its a public static void Function, in a public static class, don't see why it's not working.
The class where a function located, I want to call:
namespace Client.Modules
{
public static class Login
{
public static void Run()
{
// do something
}
}
}
The class where I want to call:
using Client.Modules;
namespace Client
{
public class Main
{
Login.Run(); // here
}
}
public class Main
{
Login.Run(); // here
}
That’s invalid: You can’t generally execute code outside methods. The only things that can go directly into classes are declarations. Put Login.Run() inside a method.
I Have created two .cs files with namespaces ,classes and methods . I want to call the classes of one .cs file into another .cs file. Can u help me how to declare namespace and use the namespace so that i can call the classes of the preceding .cs file.
Please forgive if my explanation is not correct.
Suppose i have the following code.
ClassFile1
using system
namespace namespace1
{
class c1
{
Methods()
}
}
ClassFile2
using system
//here i need to declare the namespace1 .Can u help me how to declare namespace1 in this ClassFile2//
namespace namespace2
{
class c2
{
Methods()
}
}
You can reference the fully-qualified name of the class:
namespace SecondNamespace
{
public class SecondClass
{
private FirstNamespace.FirstClass someObject;
}
}
Or you can add a using directive to the file (note, this is at the file level, not the class level) to include a specific namespace when resolving type names:
using FirstNamespace;
namespace SecondNamespace
{
public class SecondClass
{
private FirstClass someObject;
}
}
Taken from here:
namespace SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside SampleNamespace");
}
}
// Create a nested namespace, and define another class.
namespace NestedNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine(
"SampleMethod inside NestedNamespace");
}
}
}
class Program
{
static void Main(string[] args)
{
// Displays "SampleMethod inside SampleNamespace."
SampleClass outer = new SampleClass();
outer.SampleMethod();
// Displays "SampleMethod inside SampleNamespace."
SampleNamespace.SampleClass outer2 = new SampleNamespace.SampleClass();
outer2.SampleMethod();
// Displays "SampleMethod inside NestedNamespace."
NestedNamespace.SampleClass inner = new NestedNamespace.SampleClass();
inner.SampleMethod();
}
}
}
Note also that sometimes in addition to the "using" entry (I'm not quite clear on how you app is structured, if it's all one project this is probably moot) you may also need to add the reference. Also not sure what environment you're using. From VSExpress while in the project/file that's the recipient click on Project - Add Reference, select solution and then select your namespace.
This shows http://msdn.microsoft.com/en-us/library/bb311042.aspx that a reference to a public static extension class in a public static namespace can be skipped.
However, it doesn't work with public static variables.
using UnityEngine;
using System.Collections;
namespace NDefault
{
public static class TDefault
{
public static int CNT=71;
public static bool has_method(this object target,string method_name)
{
return target.GetType().GetMethod(method_name)!=null;
}
}
}
_
using UnityEngine;
using System.Collections;
using NDefault;
public class TController :MonoBehaviour
{
void Start ()
{
int t;
print (t.has_method("GetType")); //This prints "True"
print (CNT);//This creates error "The name `CNT' does not exist in the current context"
}
void Update ()
{
}
}
Am I right, that for using static variables and methods without a class reference, I have to inherit all classes from a non-static default class containing them, while for extension methods I should create a separate static class in a namespace? I.e. I can't store them together?
You can have extension methods and regular static methods/properties in the same static class. For clarity it is best to separate them.
When accessing static properties/methods you must specify the class they belong to. So to access the CNT static property it would be
int cnt = TDefault.CNT;
in your case it would then be
print (TDefault.CNT);
This rule applies for extension methods as well. For extension methods, you must have a using statement for the namespace the extension method is defined in. You must also specify the object that the extension method is for. In your example, your extension methods works for all classes. This usually is not advised unless you are adding value to all classes. you usually want to specify a particular class
public static class Extensions
{
public static bool NewMethod(this MyObject source)
{
return true;
{
}
The method above will only be available on the MyObject class, and not other classes. Unlike "normal" static methods, extension methods require an instance of an object in order to work as "extension methods". Both samples below will work.
MyObject o = new MyObject();
bool val = o.NewMethod();
// this also will get the value
val = Extensions.NewMethod(o);
it's possible?
based in another's examples, as LabelExtesios, StringExtensions, etc.
I wrote this:
namespace MessageBoxExtensions
{
public static class MessageBoxExtensionsClass
{
public static void Foo()
{
}
}
}
then:
using MessageBoxExtensions;
// ...
MessageBox.Foo();
gin an error: MessageBox.Foo();
'System.Windows.Forms.MessageBox' does not contain a definition for 'Foo'
Description
You cant do this because System.Windows.Forms.MessageBox is NOT an instance of MessageBox. MessageBox.Show() is a static method.
You cant create an instance of MessageBox because this class has no public constructor.
Update
But you can create your own class in the System.Windows.Forms namespace and use the
MessageBox in this method like this
Sample
namespace System.Windows.Forms
{
public static class MyCustomMessageBox
{
public static void Foo()
{
MessageBox.Show("MyText");
}
}
}
MyCustomMessageBox.Foo();
You are missing the this keyword from your extension method declaration.
But because System.Windows.Forms.MessageBox does not have a public constructor just static factory methods (which returns DialogResult) so you won't able the create a standalone MessageBox instance to invoke your extension method on it.
So to answer the your question:
Yes it's possible to create an extension method on MessageBox (see other answers) but you can't invoke it by MessageBox.Foo() you need an instance of MessageBox what you cannot create so it won't work.
You need to add a parameter of type MessageBox to the extension method:
public static void Foo(this MessageBox messageBox) { ... }
Then create an instance of the MessageBox before calling the method
var messageBox = new MessageBox();
messageBox.Foo();
[Update:
Unfortunately this doesn't work in case of the MessageBox since there is no public constructor. Thanks to nemesv for the hint. The following example should theoretically work, but in practice it won't. I'll leave it for reference.]
In your example you call the method on the class itself. Extension methods only apply to instances. Here's a version of your code with the above corrections applied:
namespace MessageBoxExtensions
{
public static class MessageBoxExtensionsClass
{
public static void Foo(this MessageBox messageBox)
{
// ...
}
}
}
using MessageBoxExtensions;
// ...
var messageBox = new MessageBox();
messageBox.Foo();
You must qualify the extension method parameter with a this modifier for it to be registered as an extension method.
namespace MessageBoxExtensions
{
public static class MessageBoxExtensionsClass
{
public static void Foo(this MessageBox messagebox)
{
}
}
}
What is the best way to implement polymorphic behavior in classes that I can't modify? I currently have some code like:
if(obj is ClassA) {
// ...
} else if(obj is ClassB) {
// ...
} else if ...
The obvious answer is to add a virtual method to the base class, but unfortunately the code is in a different assembly and I can't modify it. Is there a better way to handle this than the ugly and slow code above?
Hmmm... seems more suited to Adapter.
public interface ITheInterfaceYouNeed
{
void DoWhatYouWant();
}
public class MyA : ITheInterfaceYouNeed
{
protected ClassA _actualA;
public MyA( ClassA actualA )
{
_actualA = actualA;
}
public void DoWhatYouWant()
{
_actualA.DoWhatADoes();
}
}
public class MyB : ITheInterfaceYouNeed
{
protected ClassB _actualB;
public MyB( ClassB actualB )
{
_actualB = actualB;
}
public void DoWhatYouWant()
{
_actualB.DoWhatBDoes();
}
}
Seems like a lot of code, but it will make the client code a lot closer to what you want. Plus it'll give you a chance to think about what interface you're actually using.
Check out the Visitor pattern. This lets you come close to adding virtual methods to a class without changing the class. You need to use an extension method with a dynamic cast if the base class you're working with doesn't have a Visit method. Here's some sample code:
public class Main
{
public static void Example()
{
Base a = new GirlChild();
var v = new Visitor();
a.Visit(v);
}
}
static class Ext
{
public static void Visit(this object b, Visitor v)
{
((dynamic)v).Visit((dynamic)b);
}
}
public class Visitor
{
public void Visit(Base b)
{
throw new NotImplementedException();
}
public void Visit(BoyChild b)
{
Console.WriteLine("It's a boy!");
}
public void Visit(GirlChild g)
{
Console.WriteLine("It's a girl!");
}
}
//Below this line are the classes you don't have to change.
public class Base
{
}
public class BoyChild : Base
{
}
public class GirlChild : Base
{
}
I would say that the standard approach here is to wrap the class you want to "inherit" as a protected instance variable and then emulate all the non-private members (method/properties/events/etc.) of the wrapped class in your container class. You can then mark this class and its appropiate members as virtual so that you can use standard polymorphism features with it.
Here's an example of what I mean. ClosedClass is the class contained in the assembly whose code to which you have no access.
public virtual class WrapperClass : IClosedClassInterface1, IClosedClassInterface2
{
protected ClosedClass object;
public ClosedClass()
{
object = new ClosedClass();
}
public void Method1()
{
object.Method1();
}
public void Method2()
{
object.Method2();
}
}
If whatever assembly you are referencing were designed well, then all the types/members that you might ever want to access would be marked appropiately (abstract, virtual, sealed), but indeed this is unfortunately not the case (sometimes you can even experienced this issue with the Base Class Library). In my opinion, the wrapper class is the way to go here. It does have its benefits (even when the class from which you want to derive is inheritable), namely removing/changing the modifier of methods you don't want the user of your class to have access to. The ReadOnlyCollection<T> in the BCL is a pretty good example of this.
Take a look at the Decorator pattern. Noldorin actually explained it without giving the name of the pattern.
Decorator is the way of extending behavior without inheriting. The only thing I would change in Noldorin's code is the fact that the constructor should receive an instance of the object you are decorating.
Extension methods provide an easy way to add additional method signatures to existing classes. This requires the 3.5 framework.
Create a static utility class and add something like this:
public static void DoSomething(this ClassA obj, int param1, string param2)
{
//do something
}
Add a reference to the utility class on the page, and this method will appear as a member of ClassA. You can overload existing methods or create new ones this way.