Putting function in appropriate class - c#

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)

Related

Generic handling in c#

So, I have a little bit of an issue that I can't exactly wrap my head around.
So, I have a base class called Property, and I have a lot of classes that derive from that one, like IntProperty, ColorProperty and so on. Now, I also have a few of them that are of the enum type and currently they are all separate classes. I'd like to make it a generic class but here's the issue with this:
In a different part of the code I need to handle all of them. Keep in mind I can't use virtual functions for this (I'm doing something with the UnityEditor).
Currently, I have a function that takes a Property as a parameter and then I do this for all types that derive from Property:
if(property is IntProperty)
{
IntProperty intProperty = property as IntProperty;
intProperty.theValue = specific_int_function();
}
That specific_int_function is the same for all enum values privided I have the T from a generic.
Ideally I'd like to do something like this (pseud-ish code):
(using T)
{
if(property is EnumProperty<T>)
{
EnumProperty<T> enumProperty = property as EnumProperty<T>;
enumProperty.value = (T)my_enum_value_function(typeof(T));
}
}
Any idea about how I could make all this code nicer?
Hopefully I provided all the relevant information.
Edit:
It's not so much that I can't use virtual functions in those classes but I can't call any of the specific functions in that particular file. I have 2 compilation groups and only one can access those functions (EditorGUI functions for people who know what I'm talking about)
Regards,
Lorin
Keep in mind I can't use virtual functions for this (I'm doing something with the UnityEditor).
That's really what you should be doing. If you can't, then fine, but I'm leaving this note here for the benefit of other people will be reading this question and answer too.
In my experience, the least difficult way of achieving this is with a helper class, because it lets you avoid some of the reflection complexity that you would have to deal with if you used a generic helper method.
abstract class EnumPropertyHelper {
public abstract void DoSomething(Property property);
}
class EnumPropertyHelper<T> : EnumPropertyHelper {
public override void DoSomething(Property property) {
EnumProperty<T> enumProperty = property as EnumProperty<T>;
enumProperty.value = (T)my_enum_value_function(typeof(T));
}
}
Then,
if (property.GetType().IsGenericType
&& property.GetType().GetGenericTypeDefinition() == typeof(EnumProperty<>)) {
var helperType = typeof(EnumPropertyHelper<>).MakeGenericType(property.GetType().GetGenericTypeArguments());
var helper = (EnumPropertyHelper)Activator.CreateInstance(helper);
helper.DoSomething(property);
}
But you do need to jump through hoops similar to this one whatever you end up doing, because C# and .NET don't allow you to have generic code in non-generic methods.
You could use add a function pointer to the class, and each constructor could implement it's own function?
Add a property Func<void> functionPTR = null
In each class you'd have a function such as
void specific_int_function() {
//Do Something
}
In the class constructor
functionPTR = specific_int_function;
And then in the generic class
void GenericHandler() {
functionPTR();
}
I'm not sure about the syntax, but this should give you the performance you're going for.
Read up on function pointers to see how to define the return value and function parameters.

C# Passing object class as Method Parameter

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);

Can we call method in implementation class not defined in its interface using interface variable?

Is it possible to call a method in implementation class of an interface which is not defined in interface using interface variable like below:
interface ILookup {
public void someInterfaceMethod1();
public void someInterfaceMethod2();
}
...and implementation class:
public class extendedLookUpImplementor: ILookup
{
//constructor
LookUpImplementor(){
}
public void someInterfaceMethod1(){
// Implementation Code here.
}
public void someInterfaceMethod2(){
// Implementation Code here.
}
public void ExtendedMethod(){
// Implementation Code here.
}
}
In client code:
ILookup lookupVar = new LookUpImplementor();
lookupVar -> someInterfaceMethod1(); // i know it will work.
lookupVar -> someInterfaceMethod2(); // i know it will work.
My question is, can i call ExtendedMethod using lookupVar like below:
lookupVar -> ExtendedMethod(); // Note again that ExtendedMethod() is not defined in Ilookup interface/contract.
Only by casting lookupVar as extendedLookUpImplementor, or by reflection I think.
First of all as Ian1971 said, yes you can by casting it to specific type, say
ILookup lookupVar = new LookUpImplementor();
((extendedLookUpImplementor)lookupVar).ExtendedMethod(); //this should work
or alternatively using dynamic/reflection.
Having said that, I really really don't think this is a good way to do this because it would violate one of the objective of contract/interface.
For instance, if we have ILookup variable "lookupVar"
dynamic lookup = lookupVar;
lookup.ExtendedMethod(); //this would work
At any point in time, the code utilizing the object lookupVar does not guarantee that there would be a method ExtendedMethod and can throw on Exception on run time.
My real question to you would be, why you want to add a method that cannot be added in contract, what is your objective here. If the method is extending the class, try going through C# extension method as they might fit in your scenario.

custom generic collection- what is the best way to refactor it?

I have a similar problem and tried to depict it with code as it is easier to explain.
Basically I have a generic collection, so irrespective of which type of collection its instantiated as, it will have some common properties and events. And I am interested in these common properties.
Say, I have the instantiated obect of the generic collection - what is the best way to get these properties and subscribe to the events? I understand I can do it by implementing an interface and casting it to the interface definition but I don't like doing that as I am just doing it to please a single requirement. Is there a better way to refactor this?
public interface IDoNotLikeThisInterfaceDefinitionJustToPleaseGetDetailMethod
{
string Detail { get; }
event Action<bool> MyEvent;
}
public class MyList<T> : List<T>
//, IDoNotLikeThisInterfaceDefinitionJustToPleaseGetDetailMethod
{
public string Detail
{
get;
}
}
class Program
{
static void Main(string[] args)
{
MyList<int> mi = new MyList<int>();
MyList<string> ms = new MyList<string>();
MyList<char> mc = new MyList<char>();
GetDetail(mi);
GetDetail(ms);
GetDetail(mc);
}
//please note that obect need not be mylist<t>
static string DoSomeWork(Object object)
{
//Problem: I know myListObect is generic mylist
//but i dont know which type of collection it is
//and in fact i do not care
//all i want is get the detail information
//what is the best way to solve it
//i know one way to solve is implement an interface and case it to get details
var foo = myListObject as IDoNotLikeThisInterfaceDefinitionJustToPleaseGetDetailMethod;
if (foo != null)
{
//is there another way?
//here i also need to subsribe to the event as well?
return foo.Detail;
}
return null;
}
}
You can make your method generic:
static string GetDetail<T>(MyList<T> myList)
{
return myList.Detail;
}
This will allow you to call it with the same code you already have written, and completely eliminate the interface.
Edit in response to comments:
Given that you don't know the type, and you're just checking against an object, it does seem like an interface is the best approach here. Providing a common interface allows you to expose all of the members you need regardless of what's contained within the collection, which provides the correct behavior.
Make your GetDetail method generic:
static string GetDetail<T>(MyList<T> list)
{
return list.Detail;
}
EDIT: I've assumed that there are potentially multiple collection classes involved. If there's actually only one class - MyList<T> - then using a generic method is absolutely the right way to go.
i understand i can do it by implementating an interface and casting it to the interface defenition but i dont like it as i am just doing it to please one single requirement.
You're doing it to express what the collections have in common. Unless the common members are implementing an interface, they just happen to have the same name - the interface shows that they have the same intended meaning too.
Using an interface is the right way to go here - but it's not clear why your GetDetail method doesn't just take the interface as a parameter... assuming you need the method at all.

How to access static methods of generic types

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?
}

Categories

Resources