Best practise: Creating methods, different overloads - c#

Let's say, for example, we have a method, which for sake of argument we'll call MethodOne;
public void MethodOne()
{
//do stuff.
}
Now let's say we want to create an optional peramater, and we might decide to create another method with the same name, that takes different overloads, for example;
public void MethodOne()
{
//do stuff.
}
public void MethodOne(bool checkVar)
{
if(checkVar)
{
//do stuff
}
else
{
//do other stuff
}
}
So now we've got a method which has two different overload combinations(?). Is this, in practise, better than having one method, and just checking whether the optional overload is null or contains information, for example;
public void MethodOne(int? testVar)
{
if(testVar != null)
{
//do stuff
}
}
This may seem trivial with just one overload, but imagine that i've got 5 variables i want to pass through, would i create 5 methods, same name with different overloads, or just one method and check the passed variables?

There are a few workarounds for this. You could, for example, use an enumerator and an Object array as second parameter which contains real parameter values so that you know what to do with data by switching the enumerator... or you could just declare 5 Object parameters and then check for their type in a switch, box them accordingly and proceed. But both options are very bad practices.
I suggest you to stick on different overloads:
public void MethodOne(Boolean value)
{
// Process the value...
}
public void MethodOne(Int32 value)
{
// Process the value...
}
public void MethodOne(Int32 value, String text)
{
// Process the value and the text...
}
// And so on...
Or default data in parameter declarations:
public void MethodOne(Int32 integer = 1, String text = "hello", ...)
{
// Process everything inside the method...
}
Or parametrized methods (if every object type has a common processing):
public void MethodOne(params Object[] parameters)
{
for (int i = 0; i < parameters.Length; ++i)
// Check type of parameter and process the value...
}
Or methods bubbling if your design allows it (which is my favorite one as the first one is just producing a lot of code redundancies and the second one may be sometimes confusing for you or other developers working with you):
public void MethodOne(Int32 value)
{
MethodOne(value, "hello");
}
public void MethodOne(Int32 value, String text)
{
// Process everything inside the method...
}

What you can do is use optional arguments:
public void MethodOne(int testVar = 0)
{
if(testVar != 0)
{
//do stuff
}
}

You generally bubble down on overloads like this:
public void MethodOne()
{
MethodOne(1)
}
public void MethodOne(int testVar)
{
MethodOne(testVar, "test")
}
public void MethodOne(int testVar, string testString)
{
MethodOne(testVar, testString, null)
}
public void MethodOne(int testVar, string testString, object testObject)
{
// Do your actual code here
}
This would be equivalent to
public void MethodOne(int testVar = 1, string testString = "test", object testObject = null)
{
// Do your actual code here
}
But usually you should prever overloads over default parameters. Also, by 'bubbling down' like in my example you avoid having redundant code or redundant 'default parameters'

As the number of arguments increase, I wouldn't want to look through a method's nested if/else logic to determine what arguments are being used or not. It's hard to read, understand, maintain and can lead to bugs. Use overloads and keep your methods concise, lean and maintainable.

Related

Invoke Function with async method delegate in C# [duplicate]

I have several methods all with the same parameter types and return values but different names and blocks. I want to pass the name of the method to run to another method that will invoke the passed method.
public int Method1(string)
{
// Do something
return myInt;
}
public int Method2(string)
{
// Do something different
return myInt;
}
public bool RunTheMethod([Method Name passed in here] myMethodName)
{
// Do stuff
int i = myMethodName("My String");
// Do more stuff
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
This code does not work but this is what I am trying to do. What I don't understand is how to write the RunTheMethod code since I need to define the parameter.
You can use the Func delegate in .NET 3.5 as the parameter in your RunTheMethod method. The Func delegate allows you to specify a method that takes a number of parameters of a specific type and returns a single argument of a specific type. Here is an example that should work:
public class Class1
{
public int Method1(string input)
{
//... do something
return 0;
}
public int Method2(string input)
{
//... do something different
return 1;
}
public bool RunTheMethod(Func<string, int> myMethodName)
{
//... do stuff
int i = myMethodName("My String");
//... do more stuff
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
}
You need to use a delegate. In this case all your methods take a string parameter and return an int - this is most simply represented by the Func<string, int> delegate1. So your code can become correct with as simple a change as this:
public bool RunTheMethod(Func<string, int> myMethodName)
{
// ... do stuff
int i = myMethodName("My String");
// ... do more stuff
return true;
}
Delegates have a lot more power than this, admittedly. For example, with C# you can create a delegate from a lambda expression, so you could invoke your method this way:
RunTheMethod(x => x.Length);
That will create an anonymous function like this:
// The <> in the name make it "unspeakable" - you can't refer to this method directly
// in your own code.
private static int <>_HiddenMethod_<>(string x)
{
return x.Length;
}
and then pass that delegate to the RunTheMethod method.
You can use delegates for event subscriptions, asynchronous execution, callbacks - all kinds of things. It's well worth reading up on them, particularly if you want to use LINQ. I have an article which is mostly about the differences between delegates and events, but you may find it useful anyway.
1 This is just based on the generic Func<T, TResult> delegate type in the framework; you could easily declare your own:
public delegate int MyDelegateType(string value)
and then make the parameter be of type MyDelegateType instead.
From OP's example:
public static int Method1(string mystring)
{
return 1;
}
public static int Method2(string mystring)
{
return 2;
}
You can try Action Delegate! And then call your method using
public bool RunTheMethod(Action myMethodName)
{
myMethodName(); // note: the return value got discarded
return true;
}
RunTheMethod(() => Method1("MyString1"));
Or
public static object InvokeMethod(Delegate method, params object[] args)
{
return method.DynamicInvoke(args);
}
Then simply call method
Console.WriteLine(InvokeMethod(new Func<string,int>(Method1), "MyString1"));
Console.WriteLine(InvokeMethod(new Func<string, int>(Method2), "MyString2"));
In order to provide a clear and complete answer, I'm going to start from the very beginning before showing three possible solutions.
A brief introduction
All .NET languages (such as C#, F#, and Visual Basic) run on top of the Common Language Runtime (CLR), which is a VM that runs code in the Common Intermediate Language (CIL), which is way higher level than machine code. It follows that methods aren't Assembly subroutines, nor are they values, unlike functional languages and JavaScript; rather, they're symbols that CLR recognizes. Not being values, they cannot be passed as a parameter. That's why there's a special tool in .NET. That is, delegates.
What's a delegate?
A delegate represents a handle to a method (the term handle is to be preferred over pointer as the latter would be an implementation detail). Since a method is not a value, there has to be a special class in .NET, namely Delegate, which wraps up any method. What makes it special is that, like very few classes, it needs to be implemented by the CLR itself and couldn't be simply written as a class in a .NET language.
Three different solutions, the same underlying concept
The type–unsafe way
Using the Delegate special class directly.
Example:
static void MyMethod()
{
Console.WriteLine("I was called by the Delegate special class!");
}
static void CallAnyMethod(Delegate yourMethod)
{
yourMethod.DynamicInvoke(new object[] { /*Array of arguments to pass*/ });
}
static void Main()
{
CallAnyMethod(MyMethod);
}
The drawback here is your code being type–unsafe, allowing arguments to be passed dynamically, with no constraints.
The custom way
Besides the Delegate special class, the concept of delegates spreads to custom delegates, which are declarations of methods preceded by the delegate keyword. They are type–checked the same way as “normal” method invocations, making for type-safe code.
Example:
delegate void PrintDelegate(string prompt);
static void PrintSomewhere(PrintDelegate print, string prompt)
{
print(prompt);
}
static void PrintOnConsole(string prompt)
{
Console.WriteLine(prompt);
}
static void PrintOnScreen(string prompt)
{
MessageBox.Show(prompt);
}
static void Main()
{
PrintSomewhere(PrintOnConsole, "Press a key to get a message");
Console.Read();
PrintSomewhere(PrintOnScreen, "Hello world");
}
The standard library's way
Alternatively, you can stick with a delegate that's part of the .NET Standard:
Action wraps up a parameterless void method;
Action<T1> wraps up a void method with one parameter of type T1;
Action<T1, T2> wraps up a void method with two parameters of types T1 and T2, respectively,
and so forth;
Func<TR> wraps up a parameterless function with TR return type;
Func<T1, TR> wraps up a function with TR return type and with one parameter of type T1;
Func<T1, T2, TR> wraps up a function with TR return type and with two parameters of types T1 and T2, respectively;
and so forth.
However, bear in mind that by using predefined delegates like these, parameter names won't be self-describing, nor is the name of the delegate type meaningful as to what instances are supposed to do. Therefore, refrain from using them in contexts where their purpose is not absolutely self-evident.
The latter solution is the one most people posted. I'm also mentioning it in my answer for the sake of completeness.
The solution involves Delegates, which are used to store methods to call. Define a method taking a delegate as an argument,
public static T Runner<T>(Func<T> funcToRun)
{
// Do stuff before running function as normal
return funcToRun();
}
Then pass the delegate on the call site:
var returnValue = Runner(() => GetUser(99));
You should use a Func<string, int> delegate, that represents a function taking a string argument and returning an int value:
public bool RunTheMethod(Func<string, int> myMethod)
{
// Do stuff
myMethod.Invoke("My String");
// Do stuff
return true;
}
Then invoke it this way:
public bool Test()
{
return RunTheMethod(Method1);
}
While the accepted answer is absolutely correct, I would like to provide an additional method.
I ended up here after doing my own searching for a solution to a similar question.
I am building a plugin driven framework, and as part of it I wanted people to be able to add menu items to the applications menu to a generic list without exposing an actual Menu object because the framework may deploy on other platforms that don't have Menu UI objects. Adding general info about the menu is easy enough, but allowing the plugin developer enough liberty to create the callback for when the menu is clicked was proving to be a pain. Until it dawned on me that I was trying to re-invent the wheel and normal menus call and trigger the callback from events!
So the solution, as simple as it sounds once you realize it, eluded me until now.
Just create separate classes for each of your current methods, inherited from a base if you must, and just add an event handler to each.
Here is an example Which can help you better to understand how to pass a function as a parameter.
Suppose you have Parent page and you want to open a child popup window. In the parent page there is a textbox that should be filled basing on child popup textbox.
Here you need to create a delegate.
Parent.cs
// declaration of delegates
public delegate void FillName(String FirstName);
Now create a function which will fill your textbox and function should map delegates
//parameters
public void Getname(String ThisName)
{
txtname.Text=ThisName;
}
Now on button click you need to open a Child popup window.
private void button1_Click(object sender, RoutedEventArgs e)
{
ChildPopUp p = new ChildPopUp (Getname) //pass function name in its constructor
p.Show();
}
IN ChildPopUp constructor you need to create parameter of 'delegate type' of parent //page
ChildPopUp.cs
public Parent.FillName obj;
public PopUp(Parent.FillName objTMP)//parameter as deligate type
{
obj = objTMP;
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
obj(txtFirstName.Text);
// Getname() function will call automatically here
this.DialogResult = true;
}
If you want to pass Method as parameter, use:
using System;
public void Method1()
{
CallingMethod(CalledMethod);
}
public void CallingMethod(Action method)
{
method(); // This will call the method that has been passed as parameter
}
public void CalledMethod()
{
Console.WriteLine("This method is called by passing it as a parameter");
}
If the method passed needs to take one argument and return a value, Func is the best way to go. Here is an example.
public int Method1(string)
{
// Do something
return 6;
}
public int Method2(string)
{
// Do something different
return 5;
}
public bool RunTheMethod(Func<string, int> myMethodName)
{
// Do stuff
int i = myMethodName("My String");
Console.WriteLine(i); // This is just in place of the "Do more stuff"
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
Read the docs here
However, if your method that is passed as a parameter does not return anything, you can also use Action. It supports up to 16 paramaters for the passed method. Here is an example.
public int MethodToBeCalled(string name, int age)
{
Console.WriteLine(name + "'s age is" + age);
}
public bool RunTheMethod(Action<string, int> myMethodName)
{
// Do stuff
myMethodName("bob", 32); // Expected output: "bob's age is 32"
return true;
}
public bool Test()
{
return RunTheMethod(MethodToBeCalled);
}
Read the documentation here
Here is an example without a parameter:
http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string
with params:
http://www.daniweb.com/forums/thread98148.html#
you basically pass in an array of objects along with name of method. you then use both with the Invoke method.
params Object[] parameters
class PersonDB
{
string[] list = { "John", "Sam", "Dave" };
public void Process(ProcessPersonDelegate f)
{
foreach(string s in list) f(s);
}
}
The second class is Client, which will use the storage class. It has a Main method that creates an instance of PersonDB, and it calls that object’s Process method with a method that is defined in the Client class.
class Client
{
static void Main()
{
PersonDB p = new PersonDB();
p.Process(PrintName);
}
static void PrintName(string name)
{
System.Console.WriteLine(name);
}
}
I don't know who might need this, but in case you're unsure how to send a lambda with a delegate, when the function using the delegate doesn't need to insert any params in there you just need the return value.
SO you can also do this:
public int DoStuff(string stuff)
{
Console.WriteLine(stuff);
}
public static bool MethodWithDelegate(Func<int> delegate)
{
///do stuff
int i = delegate();
return i!=0;
}
public static void Main(String[] args)
{
var answer = MethodWithDelegate(()=> DoStuff("On This random string that the MethodWithDelegate doesn't know about."));
}

C# methods with variable paramterlist as parameter

Hi I'm currently trying to pass methods (with no return value) as parameters to another method (so that they can be called from within the methods).
The problem I'm currently having is, that I'm using Action in the parameterlist and thus need to exactly define which parameters this method takes.
The question thus is: Is there any way to omit this? Thus that I don't have to define which parameters exactly the method has in the parameterdeclaration?
Codeexample:
public void A(int myint)
{
Console.WriteLine(myint.ToString());
}
public void B(int myint1, int myint2)
{
Console.WriteLine((myint1 + myint2).ToString());
}
public void myQuestionMethod(Action<int> parameterMethod)
{
//....Dosomething special by creating the parameters within and calling the given methods
}
myQuestionMethod(A);
myQuestionMethod(B);
Thus Aciton parameterMethod can that be replaced by something else that allows me to give methods as parameters who have differing parameters?
Edit:
I forgot to mention that the TYPE of the parameters is also not fixated.
Thus a function C could exist with (int param1, String param2)
No. There is no way to do this with the Action delegate (that's why there are 16 overloads).
You could opt, if the variables are all of the same type and have the same meaning, to create an array of integers:
public void A(params int[] myint)
{
}
public void myQuestionMethod(Action<int[]> parameterMethod)
{
//....Dosomething special by creating the parameters within and calling the given methods
}
Depending on how big your methods are, you could go for just Action and use anonymous methods rather than explicitly defining the functions
public void myQuestionMethod(Action parameterMethod)
{
//
}
...
myQuestionMethod(() => Console.WriteLine(myInt.ToString()));
myQuestionMethod(() => Console.WriteLine((myInt1 + myInt2).ToString()));
One solution would be to use reflection. Of course don't use it unless you do not have any other choice (specifying a method using its name should be avoided if possible):
public class Foo
{
public void A(int myint)
{
Console.WriteLine(myint.ToString());
}
public void B(int myint1, int myint2)
{
Console.WriteLine((myint1 + myint2).ToString());
}
public void myQuestionMethod(string parameterMethodName, params object[] parameters)
{
var method = this.GetType().GetMethod(parameterMethodName, BindingFlags.Instance | BindingFlags.Public);
method.Invoke(this, parameters);
}
}
public class Test
{
public static void Main()
{
var foo = new Foo();
foo.myQuestionMethod("B", 1, 2);
Console.Read();
}
}

Determine at runtime if a cast is allowed (C#)

I have a C# wraper class with a series of methods accepting various data types:
public class MyClass
{
public void ProcessString(string Value) { // implementation }
public void ProcessInt(int? Value) { // implementation }\
public void ProcessOther(MyClass Value) { // implementation }
}
I now want to add a generic ProcessObject() method to avoid the need to explicitly cast an object before calling a relevant process method:
public void ProcessObject(object Value)
{
if (CanCastToString(Value)
{
ProcessString((string)Value);
}
else if (CanCastToInt(Value))
{
ProcessInt((int?)Value);
}
// etc...
}
The trouble is that I don't know what my CanCastToInt methods should be - I need these methods to be able to be robust and deal with things like nullable types and other user defined casts.
How can I do this? All I want to know is if a given object can be cast to a given type, i.e. whether or not:
(SomeType)Value
Will work.
There are two main ways this is usually done:
if (Value is SomeType)
{
// Do something with a cast
}
or
var v = Value as SomeType;
if (v != null)
{
// Value was successfully cast as SomeType
}
When working with structs or intrinsic types, make them nullable:
var v = Value as int?;
if (v != null)
{
ProcessInt(v.Value);
}
you need is operator. CanCastToString(x) -> x is string.
Why not expose your processing API directly, with overloads for various parameters?
public class MyClass
{
public void Process(string Value) { // implementation }
public void Process(int Value) { // implementation }\
public void Process(MyClass Value) { // implementation }
public void Process(object Value) { // catch all method. Handle unknown entities, e.g. call ToString() }
}
EDIT With some generics magic you can have a single interface method, a bunch of helper methods that do the work and one catch-all method where you handle corner cases.
public class MyClass
{
void DoProcess(string Value) { // implementation }
void DoProcess(int Value) { // implementation }\
void DoProcess(MyClass Value) { // implementation }
void DoProcess(object Value) {
// catch all method. Handle unknown entities, e.g. call ToString()
}
public void Process<T>(T value) {
//this method will call the right overload of DoProcess depending on the compile time type of value. If there isn't a match, it goes to DoProcess(object)
DoProcess(value);
}
}
This way you avoid boxing for fundamental types and have slightly better type safety.
For your catch-all method you can try using Type.IsAssignableFrom method. For example:
if (typeof(short).IsAssignableFrom(Value)
DoProcess((short)Value);
if (typeof(byte).IsAssignableFrom(Value)
DoProcess((byte)Value);
I do recommend that you read Eric Lippert's essay about representation casts. Hopefully, after doing that, you will come to realisation that it might just be easier to have an overload for each supported type. Also, you might realise that dealing with unboxing value types could be a road to hell.
If (unlike OP?) you don't know the type involved until runtime you may try to employ some variation of this:
http://codegoeshere.blogspot.com/2007/05/dynamic-cast-in-c.html
public void QuickTest()
{
object stringObj = "string";
object nullableInt1 = (int?)null;
object nullableInt2 = (int?)1;
object decimalObj = 1.5m;
ProcessObject(stringObj);
ProcessObject(nullableInt1);
ProcessObject(nullableInt2);
ProcessObject(decimalObj);
}
public void ProcessObject(object value)
{
if (value == null)
{
Debug.WriteLine("null");
return;
}
if (value is string)
{
Debug.WriteLine((string)value);
return;
}
string stringValue = value.ToString();
int intTemp;
if (int.TryParse(stringValue, out intTemp))
{
Debug.WriteLine(intTemp);
return;
}
decimal decimalTemp;
if (decimal.TryParse(stringValue, out decimalTemp))
{
Debug.WriteLine(decimalTemp);
return;
}
// etc...
}

Resolving a parameter name at runtime [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Finding the Variable Name passed to a Function in C#
In C#, is there a way (terser the better) to resolve the name of a parameter at runtime?
For example, in the following method, if you renamed the method parameter, you'd also have to remember to update the string literal passed to ArgumentNullException.
public void Woof(object resource)
{
if (resource == null)
{
throw new ArgumentNullException("resource");
}
// ..
}
One way:
static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}
This code also requires a supporting function:
static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
Enforce.That(properties.Length == 1);
return properties[0].Name;
}
Basically the code works by defining a new Anonymous Type with a single Property consisting of the parameter who's name you want. GetName() then uses reflection to extract the name of that Property.
There are more details here: http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html
Short answer: No, there isn't. (Is that terse enough? ;)
(EDIT: Justin's answer probably counts. It leaves a bad taste in my mouth, but it accomplishes the goal of "no need to put the parameter name into a string". I don't think I'd really count AOP though, as that's really changing to a completely different approach rather than answering the original question of getting a parameter name from within a method.)
Longer answer: There's a way to find out all the parameters of a method, but I don't think it's useful in this case.
Here's an example which displays the parameter names from a couple of methods:
using System;
using System.Reflection;
class Test
{
static void Main()
{
Foo(null);
Bar(null);
}
static void Foo(object resource)
{
PrintParameters(MethodBase.GetCurrentMethod());
}
static void Bar(object other)
{
PrintParameters(MethodBase.GetCurrentMethod());
}
static void PrintParameters(MethodBase method)
{
Console.WriteLine("{0}:", method.Name);
foreach (ParameterInfo parameter in method.GetParameters())
{
Console.WriteLine(" {0} {1}",
parameter.ParameterType,
parameter.Name);
}
}
}
So that does that, but if you have multiple parameters and you wanted to throw an appropriate exception, how would you know (in a safe way) which to use? Ideally you want something like:
public void Woof(object resource)
{
if (resource == null)
{
throw new ArgumentNullException(infoof(resource));
}
// ..
}
where the mythical infoof operator would return a ParameterInfo. Unfortunately this doesn't exist.
I dealt with this very same issue. There are a couple of ways of getting the parameter name but the most performant is to dip down into the IL. You can see an example of my implementation on my blog post on this very issue Taking the pain out of parameter validation.
The one caveat to this approach is you need to pass the parameter name in as a delegate but it is small price to pay for cleaner code:
public void SomeMethod(string value)
{
Validate.Argument(() => value).IsNotNull().IsNotEmpty();
}
Which is somewhat cleaner and clearer than:
public void SomeMethod(string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (value == string.Empty)
{
throw new ArgumentException("Value cannot be an empty string.", "value");
}
}
The static method approach has allowed me to chain a number of methods together in a fluent interface. Initially an Argument object is returned which only allows a basic null test which returns a ReferenceArgument object which can then have additional validation. If the object under test is a value type then different tests are available.
The API allows for a number of common tests but it would be hard to capture all the possible tests so to provide flexibility a generic test method allows an expression or function to be provided and in the case of the former the expression can actually be used as the error message.
My example only covers a few of the basics but you can easily expand the interface to check for ranges and throw ArgumentOutOfRangeExceptions or test objects inherit from a specific base class or implement an interface. There are some similar implementations but I have not as yet seen any that get the parameter name.
You can get this information using AOP. You can define an intercept that is invoked before method execution and throw the exception there. This also takes care of the problem that null checking is a cross-cutting concern.
PostSharp is a good simple implementation of AOP.
Here's what your code would look like (haven't tested, but it should get you very close)
[AttributeUsage(AttributeTargets.Parameter)]
public class CanBeNullAttribute : Attribute
{
private readonly bool canBeNull;
public CanBeNullAttribute()
: this(true)
{
}
public CanBeNullAttribute(bool canBeNull)
{
this.canBeNull = canBeNull;
}
public bool AllowNull
{
get { return canBeNull; }
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class EnforceNullConstraintAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
object[] arguments = eventArgs.GetArgumentArray();
ParameterInfo[] parameters = eventArgs.Delegate.Method.GetParameters();
for (int i = 0; i < arguments.Length; i++)
{
if (arguments[i] != null) continue;
foreach (CanBeNullAttribute attribute in parameters[i].GetCustomAttributes(typeof(CanBeNullAttribute), true))
{
if (!attribute.AllowNull) throw new ArgumentNullException(parameters[i].Name);
}
}
base.OnInvocation(eventArgs);
}
}
Now, you can modify your method:
[EnforceNullConstraint]
public void Woof([CanBeNull(false)] object resource)
{
// no need to check for null, PostSharp will weave it at compile time
// execute logic assured that "resource" is not null
}
You might want:
1)
public static void ThrowIfNull<T>(Expression<Func<T>> expr)
{
if (expr == null || expr.Compile()() != null) //the compile part is slow
return;
throw new ArgumentNullException(((MemberExpression)expr.Body).Member.Name);
}
or
2)
public static void ThrowIfNull<T>(Expression<Func<T>> expr)
{
if (expr == null)
return;
var param = (MemberExpression)expr.Body;
if (((FieldInfo)param.Member).GetValue(((ConstantExpression)param.Expression).Value) == null)
throw new ArgumentNullException(param.Member.Name);
}
And call it:
Class.ThrowIfNull(() => resource);
But that's not what you would want probably. Its also a lot slower 1) is abt 1000 times slower than 2). May be:
3)
public static void ThrowIfNull<T>(this T item) where T : class
{
if (item == null)
return;
var param = typeof(T).GetProperties()[0];
if (param.GetValue(item, null) == null)
throw new ArgumentNullException(param.Name);
}
And call it:
new { resource }.ThrowIfNull();
Cleaner, much faster than above 2! :)
You can also extend these methods for properties of objects. For eg.,
new { myClass.MyProperty1 }.ThrowIfNull();
You can cache property values to improve performance further as property names don't change during runtime. See related question Finding the variable name passed to a function

Overloaded method calling overloaded method

I have a method that I'm writing that is calling another overloaded method inside it. I'd like to only write one outer method, since the parameter to the outer method is being passed to the inner one. Is there a way to do this?
I tried using generics, but I don't know enough about this so it isn't working:
public void OuterMethod<T>(T parameter)
{
InnerMethod(parameter); // InnerMethod accepts an int or a string
}
I know that I can do this:
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter);
}
But I'd rather do this the right way instead of copying/pasting code. What's the best way to accomplish this?
You can do this in C++ but not in C# (unless the inner method can also be generic instead of overloaded).
Alternatively (if you won't take 'no' for an answer), you can do a run-time switch on type, like for example ...
public void OuterMethod(object parameter)
{
if (parameter is int)
InnerMethod((int)parameter);
else if (parameter is string)
InnerMethod((string)parameter);
else
throw new SomeKindOfException();
}
... but obviously this is a run-time, not a compile-time check.
But I'd rather do this the right way instead of copying/pasting code.
You can also write software to write your outer methods (e.g. using System.CodeDom classes) instead of writing them by hand, but this is probably more trouble than it's worth.
Like the others said, you can't really do what you are trying to do and the option you stated in your question is the best bet.
You would actually have to convert the value if you use the generic. Otherwise you can downcast by accepting an Object as ChrisW suggests.
public void OuterMethod<T>(T parameter)
{
T temp = parameter;
if (temp is string )
InnerMethod(Convert.ToString(temp));
if (temp is int)
InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
}
Here is a link to the overview of Generics: http://msdn.microsoft.com/en-us/library/ms172193.aspx
From your description this seems like over-optimization.
How about:
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter**.ToString()**);
}
You can use a dynamic type to defer the overload resolution until run-time.
public void OuterMethod(dynamic parameter)
{
InnerMethod(parameter);
}
public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }
Caveat Expressions of type dynamic are not resolved or type checked by the compiler. And there might be a performance penalty as well.
If OuterMethod always calls InnerMethod, and InnerMethod only accepts an int or string, then OuterMethod<T> doesn't make any sense.
If the only difference is that one calls InnerMethod(int) and the other calls InnerMethod(string) you could do something like this:
public void OuterMethod(string parameter)
{
InnerMethodA(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethodA(parameter);
}
private void InnerMethodA(object parameter)
{
// Whatever other implementation stuff goes here
if (parameter is string)
{
InnerMethodB((string) parameter);
}
else if (parameter is int)
{
InnerMethodB((string) parameter);
}
else
{
throw new ArgumentException(...);
}
}
private void InnerMethodB(string parameter)
{
// ...
}
private void InnerMethodB(int parameter)
{
// ...
}
Ok I have a similar situation, its an access control method in my business logic.
There is a save function that could be applied to any of my persistance layer objects.
so that looks like this
public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
{
if(CanWrite(user, entity))
{
entity.save();
}
else
{
throw new Exception("Cannot Save");
}
}
How ever I have some custom code for certain entities in terms of Access Control so I wrote the following, it looks for a method more suitable to the question using System.Reflection, "can this entity be written by this user?"
public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
{
int? clubId = null;
MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
if(methodInfo != null)
{
return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
}
else
{
//generic answer
}
return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
}
Now every time I add or remove a method, I only have to add or remove it in one place

Categories