I was reading some C# tutorial, and suddenly it strikes me that I have never attempted to use object class as parameter when creating a method.
For example, I would have never thought of this:
static void GiveBookAName(Gradebook book, string bookName)
{
book.Name = bookName;
}
I am sure I would have done something like this:
public void GiveBookAName(string bookName)
{
Name = bookName;
}
//in other class
Gradebook book = new Gradebook()
book.GiveBookAName("TheGradebook");
Because of that, I tend to have Class instantiation here and there. What I meant is, if I need to access Class X in Class A & B, then I will instantiate Class X in both Class A & B. Now I realize if I start passing object class as parameter, I can have all my instantiations in one place (usually the class with Main()). Is that necessary?
It all depends all the context. The general rule of this kind of stuff is, if you think it makes sense to do this, then do it.
In your book naming method, I don't think you should pass the book as a parameter. Users of your API should be able to name the books using this:
book.Name = someStuff;
So you should not the book-naming method in another class because why should it be? The other class is not responsible for naming a book, right? Then let the book do it! Put the naming method in the Book class.
Actually I don't really pass object class as a parameter. I think that is the "functional" way of doing things, not object-oriented.
Let us look at another situation. You are using a class called X in the core library and you want to add a method to X. Now you might think you should pass an X object to the method like did with the Book because you certainly can't edit a class in core library! So this is your method:
public void DoStuffWithX(X x, int param) {
}
And you put this in another class. Well since C# 3, extension methods are added so you can do something like this:
public static void DoStuff (this X x, int param) {
}
Now you can call this method with an X object!
x.DoStuff(10);
Also I see that you always need to instantiate a class you access the method. By the nature of these "passing object class as parameter" methods, they should not have to be instantiated before calling. In other words, you should mark them static so that you can call it like this:
YourClassName.SomeMethod (parameter);
instead of:
YourClassName obj = new YourClassName ();
obj.SomeMethod (parameter);
Related
I have a significant number of classes which share the same method name, but don not share a common base/interface. I cannot touch these classes, however, can I call the method irrespective of the defining class?
Eg:
Namespace n1: class A { void M1(n1.CustObj ob1){} }
Namespace n2: class B { void M1(n2.CustObj ob1){} }
Would it be possible to abstract from these common methods/parameters, like so?
method(Object obj)
{
obj.M1(new CustObj() {
x = 3;
}); // CustObj can either belong to n1 or n2
}
You have a number of classes, each of which has a method, with the same name, but with a different signature. The identical method names are a red herring here therefore as they are different methods.
This therefore rules out using dynamic or reflection to provide a single method that can handle all of them, unless you then hard-code tests for each type within the one method, or take Jonathan Wood's approach of passing in an existing instance of CustObj via a dynamic parameter too.
One solution might be to create extension methods for each type:
public void Method(this A obj)
{
obj.M1(new n1.CustObj()
{
x = 3
});
}
public void Method(this B obj)
{
obj.M1(new n2.CustObj()
{
x = 3
});
}
and so on. Then at least you can do someObj.Method(); on A, B and so forth.
You could use either the dynamic keyword or reflection.
Of the two, I prefer dynamic. However, since your constructor argument is also a different type you'd need to do something like this:
void method(dynamic obj, dynamic arg)
{
arg.x = 3;
obj.M1(arg);
}
I understand it's unlikely that your code is set up to do this but you haven't shown much of how your method is used. And in the end, this might be the best you can do if you're unable to modify the existing classes.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have a method that takes a string argument (a file path), and i wanna make it acessible to all forms.
I know that when i use
public static methodname(string path) { //code }
it will work on all forms as long as i call it, and when i dont have static there i have to instantiate it.. the thing is.. why this difference? What does it really means to instantiate? I've read a few topics about it, but i couldn't quite understand how, can you take the time to explain it to a amateur beginner?
This tells the compiler that he method is entirely self-contained, and does not rely on or utilize any object state, or instance-based properties or fields of the class it is defined in. As a consequence, you do not need to instantiate an instance of the type (class or struct) in order to use this method. It becomes like a global function or subroutine which you can call simply by name, (you must use the class/struct name and method name) without any preparation.
to call non-static method MyMethod() on class foo
var f = new foo();
f.MyMethod();
to call static method MyMethod() on class foo
foo.MyMethod();
You can define static methods in a non-static class, (if the method does not rely on any object state doesn't mean the object does not have any state...). but you cannot put non-static methods in a static class (if the method requires access to object state, then it obviously can't be in a class that has no state).
Now you can write a method that does not require object state, and neglect to declare it as static. Then it would require the same usage syntax like a non-static method even though it is functionally static. That is an error the compiler will accept (although many tools like Resharper will warn you about this).
You use non-static classes or object oriented classes, if you want to maintain a state.
When you use static classes, there isn't any state.
For example:
class HelloWorld
{
public string Name {get;set;}
public void SayHello()
{
Console.WriteLine(Name + " hello!");
}
public void SayHi()
{
Console.WriteLine(Name + " hi!");
}
}
You would use the above like this:
HellowWorld obj = new HelloWorld();
obj.Name = "John";
obj.SayHi();
obj.SayHello();
If that was a static class:
static class HelloWorld
{
public static void SayHello(string Name)
{
Console.WriteLine(Name + " hello!");
}
public static void SayHi(string Name)
{
Console.WriteLine(Name + " hi!");
}
}
You would call the above like this:
HelloWorld.SayHello("John");
HelloWorld.SayHi("John");
As you can see, you are repeating yourself.
So it all depends on how you want the class to behave. If you want do and forget, then static class is your friend. If you don't want it to forget something, then use Objects
This is classic programming. Static methods are used when all the data you need is from the parameter. Also static methods are called upon a class. When you make a method static then it uses instance variables to do something. Instantiontain allows a user to initialize all fields in that class then the user can call a method upon that object that behind the scenes uses instance variables to do something.
As you said, a non-static method means that it belows to an object (so you have to instantiate one in order to use the method. On the other hand, a static method below to the class, so when you call it, it has nothing to do with an object.
For example:
class C{
static int f(int i){return i+1;}
}
C.f(2); // returns 3
You only can do it if the method is static, it is, it belongs to a class, not an object. If f() were not be static, you have to instantiate one object to use it:
class C{
int f(int i){return i+1;}
}
C.f(2); // invalid!
C c = new c(); c.f(2); // returns 3
On the other hand, this code is invalid:
class C{
int a;
static int f(){return a;}
}
C.f(); // Invalid: each instance of C has it own attribute a.
public class BusinessObjects<O>
where O : BusinessObject
{
void SomeMethod()
{
var s = O.MyStaticMethod(); // <- How to do this?
}
}
public class BusinessObject
{
public static string MyStaticMethod()
{
return "blah";
}
}
Is there a correct object oriented approach to accomplishing this or will I need to resort to reflection?
EDIT: I went too far in trying to oversimplify this for the question and left out an important point. MyStaticMethod uses reflection and needs the derived type to return the correct results. However, I just realized another flaw in my design which is that I can't have a static virtual method and I think that's what I would need.
Looks like I need to find another approach to this problem altogether.
You can't access a static method through a generic type parameter even if it's constrained to a type. Just use the constrained class directly
var s = BusinessObject.MyStaticMethod();
Note: If you're looking to call the static method based on the instantiated type of O that's not possible without reflection. Generics in .Net statically bind to methods at compile time (unlike say C++ which binds at instantiation time). Since there is no way to bind statically to a static method on the instantiated type, this is just not possible. Virtual methods are a bit different because you can statically bind to a virtual method and then let dynamic dispatch call the correct method on the instantiated type.
The reason you can't reference the static member like this:
O.MyStaticMethod();
Is because you don't know what type O is. Yes, it inherits from BusinessObject, but static members are not inherited between types, so you can only reference MyStaticMethod from BusinessObject.
If you are forcing O to inherit from BusinessObject, why not just call it like this:
void SomeMethod()
{
var s = BusinessObject.MyStaticMethod(); // <- How to do this?
}
public static FirstObjectType GetObject(SecondObjectType secondobjectType)
{
do something
}
Where should I put this function? Should I put it in SecondObjectType class or FirstObjectType class in terms of code readability, customs and traditions? Should the function be included in the return class or the parameter class from your experience?
Thanks for your answer.
I usually put the method in the class that has the same type as the return type of the method.
eg:
public static FirstObjectType GetObject(SecondObjectType secondobjectType)
{
do something
}
would go in the FirstObjectType class.
Alternatively you can use the Factory Pattern and have a factory for getting the objects you need. Which could give you code simliar to the following:
FirstObjectTypeFactory.GetObject(SecondObjectType secondObjectType)
Then you always know which factory to get the object from based on its return type.
This is way to vague to answer, but I'll give a few general tips
If you have a collection of FirstObjectTypes and are trying to find the one that matches SecondObjectType, then it belongs to the class that owns the collection. This could be a factory pattern.
If you are always creating a new FirstObjectType, it could just be a constructor for FirstObjectType.
Does SecondObjectType have to have knowledge of FirstObjectType? If so, then it I would consider making it a method on SecondObjectType.
There are a million other scenarios and there is no one size fits all.
I'll create an Extension Method for that.
Just add this in the signature
public static FirstObjectType GetObject(this SecondObjectType secondobjectType)
{
//do something
}
After that you can do:
SecondObjectType sobj = new SecondObjectType()
//code
FirstObjectType fobj = sobj.GetObject();
And put it with my other extension method file like ExtensionMethods.cs.
Or if the class containing the GetObject method is static too, put it in the same class (In this case in the SecondObjectType's class)
I'm trying to create a function in C# which will allow me to, when called, return a reference to a given class type. The only types of functions like this that I have seen are in UnrealScript and even then the functionality is hard coded into its compiler. I'm wondering if I can do this in C#. Here's what I mean (code snippet from UnrealScript source):
native(278) final function actor Spawn
(
class<actor> SpawnClass,
optional actor SpawnOwner,
optional name SpawnTag,
optional vector SpawnLocation,
optional rotator SpawnRotation
);
Now in UScript you would call it like this...
local ActorChild myChildRef; //Ref to ActorChild which Extends 'actor'
myChildRef = Spawn(class'ActorChild' ...); //rest of parameters taken out
myChildRef.ChildMethod(); //method call to method existing inside class 'ActorChild'
Which will return a reference to an object of class 'ActorChild' and set it to variable 'myChildRef.' I need to do something similar within C#.
I've looked into Generics but it seems that to use them, I need create an instace of the class where my function lies and pass the 'generic' parameter to it. This isn't very desirable however as I won't need to use the 'Spawn' function for certain classes but I would still need to add the generic parameter to the class whenever I use it.
I guess a simplified question would be, how can I return a type that I do not know at compile time and when the different classes could be far too many to trap.
Pseudo-Code (sticking to UScript class names, i.e. Actor):
//Function Sig
public class<Actor> Create(class<Actor> CreatedClass)
{
return new CreatedClass;
}
//Function call
ActorChild myChild = Create(class'ActorChild');
Any ideas?
EDIT: I would like to avoid explicit typecasts that would occur from the class calling Created. If I can typecast to the desired object within the Created method and return the 'unknown type' whatever that may be, I would be extremely happy.
EDIT 2: Thanks for your answers.
Rather than use a generic class, use a generic method:
public T Spawn<T>() where T : new()
{
return new T();
}
Having said that, I assume you want to do more than just blindly create an instance, otherwise you could just call new MyClass() yourself.
You can use the class System.Type to represent classes. To get references to type objects, you either use typeof (in a scope where the class is actually defined)
System.Type t = typeof(ActorChild);
or the Type.GetType function (if you only know the name of the type)
System.Type t = Type.GetType("NamespaceFoo.ActorChild");
You can then use the reflection API to create an instance
public object Create(System.Type ClassToCreate)
{
return ClassToCreate.GetConstructor(Type.EmptyTypes).Invoke(null);
}
What you're trying to accomplish can be done quite easily with Reflection and something called Dynamic Method Invocation.
Basically, you'll be using the Type object, the Activator.CreateInstance Method and some other nice classes like MethodInfo and ParameterInfo.
Here's an example to get you started:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Reflection
{
class SomeClass
{
private string StringPrimer = "The parameter text is: ";
public SomeClass(string text)
{
Console.WriteLine(StringPrimer + text);
}
public string getPrimer() //supplies the Primer in upper case, just for kicks
{
return StringPrimer.ToUpper();
}
}
class Program
{
static void Main(string[] args)
{
SomeClass s = new SomeClass("this is an example of the classes normal hard-coded function.\nNow try feeding in some text");
string t = Console.ReadLine();
Console.WriteLine("Now feed in the class name (SomeClass in this case)");
Type myType = Type.GetType("Reflection."+Console.ReadLine()); //Stores info about the class.
object myClass = Activator.CreateInstance(myType, new object[] { t }); //This dynamically calls SomeClass and sends in the text you enter as a parameter
//Now lets get the string primer, using the getPrimer function, dynamically
string primer = (string)myType.InvokeMember("getPrimer",
BindingFlags.InvokeMethod | BindingFlags.Default,
null,
myClass,
null); //This method takes the name of the method, some Binding flags,
//a binder object that I left null,
//the object that the method will be called from (would have been null if the method was static)
//and an object array of parameters, just like in the CreateInstance method.
Console.WriteLine(primer);
}
}
}