I want to write a generic function to calculate factorial in C# ... like:
static T Factorial<T>(T n)
{
开发者_如何学运维 if (n <= 1)
return 1;
return Factorial<T>(n - 1);
}
but obviously having restriction that we can't perform operations on type 'T
'. any alternative?
The problem is that generics don't support operators because they are static methods, and not part of an interface. However, you could probably use Generic Operators, which is available in the Miscellaneous Utility Library.
You would need to add a delegate parameter which performs the multiplication. Something like this
delegate T Multiply<T>(T a, T b);
So then your function would be defined like this:
static T Factorial<T>(T n, Multiply func)
{
... your code here
}
So when your factorial function is called, the caller would pass in the multiplication function:
int x = Factorial<int>(5, (a,b) => a * b);
There is no easy way to do this. I have seen some solutions that work around the problem, but they are fairly complicated. That said, if you really want to do this here are a few ideas:
If you can use .Net 4, you can cast
n
todynamic
and then perform the addition. You lose safety, of course - you could get an exception at runtimeYou could always manually check the type from within your factorial function: If
n
is a short, cast to short, ifn
is a double, cast to double... etc. That is complicated and defeats part of the value of generics, but the outside API at least looks simple.
When's the last time you took the factorial of a string, or a character? Why do you ever need a factorial of type T????
Besides this has been said numerous (prolly 1 million times now). When you need to use a generic you need to tell the compiler the type.
For instance what if I had a generic stack class? C# needs to know the elements type when I create my stack.
Otherwise it makes no sense for:
Stack<T> s = new Stack<T>();
s.Push(????); //how do I add items to the stack if we don't know what T is?
Instead you need to specify:
Stack<int> s = new Stack<int>();
s.Push(5);
s.Push(7);
This isn't specifically addressing your question about making the method generic, but your method as it stands will never return anything other than 1.
Supposing you were only working with integers, it should look like this:
static int Factorial(int n)
{
if (n <= 1)
return 1;
// note the multiplication in this step
return n * Factorial(n - 1);
}
public T Factorial<T>(T a, T b, Multiply<T> delegateMutliply, Difference<T> diffDelegate, BaseCondition<T> baseDelegate)
{
if (!baseDelegate(a, b))
return b;
return delegateMutliply(a, Factorial<T>(diffDelegate(a), b, delegateMutliply, diffDelegate, baseDelegate));
}
int y = p.Factorial(3, 1, (a, b) => a * b, (a) => --a, (a, b) => (a <= b) ? false : true);
Super old question but I'd like to add my 2 cents.
Factorial functions require f* = i
A quick function for the example above is:
class FindFactorial
{
static void Main()
{
Console.WriteLine("Please enter your number: ");
int n = int.Parse(Console.ReadLine());
int factorial = 1;
for (int i = 1; i <= n; i++)
{
factorial *= i;
}
Console.WriteLine(factorial);
}
}
精彩评论