This question already has answers here:
Is there a constraint that restricts my generic method to numeric types?
(24 answers)
Closed 8 years ago.
Is there a way to limit typing of T to be able to add default values to the function parameters?
public class Identity<T>
{
public readonly T Seed;
public readonly T Increment;
public Identity(T seed = 1, T increment = 1)
{
Seed = seed;
Increment = increment;
}
}
It is the T seed = 1 that i want to be able to do and maybe limit the T to non decimal numeric types like short, int, long...
You can only set "default" values that can be evaluated at compile-time and can be converted to all possible values of T. One example is using default:
public void Add(T parent = default(T))
{
....
}
Which doesn't work for your case, unless you want to treat "0" as a "magic" case and treat it as "1". But how would you implement it without restricting T to numeric values? (which you can't do with generics either)
The actual problem is that there's (probably) no way at all to specify a default value for a parameter of type T..
IF you can do it (I dont remember), than you could only specify:
T param1 = null // for T: class
T param1 = default(T) // for T: any
// T param1 = new T() // for T: new() -- cannot be possible, see Servy's comment
because there are no other "constructors" available for a generic type parameter T!
The compiler treats the T as an Object that has no operations and no constructors and no cast/conversions other than specified by the where clauses and/or the ones always inherited from object. Since you can specify only the above ops/requirements.. I think it cannot be done. Generics are not C++ templates ;)
Related
I'm bone new to generics in C#, and I'm attempting to create a method that will use generics. I tripped across the where keyword when attempting to create a local variable, so I'm sure that it will be part of the solution.
The reason for this is I have several different enum variables but the method would do the same to each (given a string that is one of the enum's defined values, toggle it on, using the enum like a bit field).
I have most of this together, the part I'm now stuck at is being able to tell the generic method it's ok to allow "|=" as I'm certain any type passed in will support the operator.
I would like to be able to maintain generality, if possible, so could either be an enum or a List and I would execute different code paths depending on the type.
Example of what I'm taking about
enum someType { value1 = 1<<0, value2 = 1<<1, value3 = 1<<2 }; // and so on
// some more enums
private T someMethod<T>(string myIdentifyers)
where T: new()
{
// suppose myIdentifiers is 1 more more of the valid enum options
// assume that the correct strings and enum combinations will be passed
T retval = new T();
while () {
// assume a loop with a method call that parses off one identifyer at a time
// if I have to convert the enum to an int first, so be it, but
// at this point I can't tell it that a cast to int exists
retval |= (T)System.Enum.Parse( typeof(T), oneIdentifyer, false );
}
return retval;
}
I would try something like this (pseudocode):
[Flags]
enum someType { value1 = 1<<0, value2 = 1<<1, value3 = 1<<2 }; // and so on
// some more enums
private T someMethod<T>(string myIdentifyers)
where T: struct, new()
{
// check if enum
if (typeof(T).BaseType != typeof(Enum)) // we should probably check for the flags attribute too
throw new Exception();
// suppose myIdentifiers is 1 more more of the valid enum options
// assume that the correct strings and enum combinations will be passed
int retval = 0;
while () {
// assume a loop with a method call that parses off one identifyer at a time
// if I have to convert the enum to an int first, so be it, but
// at this point I can't tell it that a cast to int exists
retval |= (int) (object) System.Enum.Parse( typeof(T), oneIdentifyer, false );
}
return (T) (object) retval;
}
It's not possible to express enum generic-constraints as of C# 4. Nor is it possible to express operator-constraints.
That said, I think you're looking for a method like this:
public static T AssembleFlagsEnum<T>(IEnumerable<string> names) where T : struct
{
return (T)(object)names.Aggregate(0,
(valSoFar, name) => valSoFar | Convert.ToInt32(Enum.Parse(typeof(T), name)));
}
Note that this doesn't validate that the type is a [Flags] enum. Nor will it work for enums which have underlying-types other than int.
In general, there's no good way to invoke operators on a generic type, although there are some kludges and workarounds that can help out in some circumstances.
See this similar question: Generic C# Code and the Plus Operator
In this case, since you know your enums cast to and from int, I think Bruno's method is the way to go.
Unfortunately it's not possible.
You can restrict with the struct constraint to say value type but obviously that includes more than integers. The only thing you could then do is early in the code to check on the actual type.
Supported constraint restrictions are described at http://msdn.microsoft.com/en-us/library/d5x73970.aspx
You can't do operator constraints - see Solution for overloaded operator constraint in .NET generics
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
passing an empty array as default value of optional parameter in c#
This code is correct in C# 4.0
static void SomeMethod(int x, int y = 5, int z = 7)
{
}
SomeMethod(1);
but when applied on arrays it gives me errors
private static void diagonalFill(int[,] a,int[] fillType = {0,-1},int[] diagFill = {-1,1})
{
}
diagonalFill(array);
Could anyone show me the right way? 10x
Default parameter values are not possible with complex reference values. The first one works because the parameters are primitives that are stored on the stack and are copied by value. Arrays are complex reference values so they must first be allocated before they can appear as parameters.
Edit:
#Henk Holterman's comment is well taken. I don't have direct knowledge of whether the stack or heap come into play on this so this information is either mistaken or misleading. The primary criteria I am aware of is that only primitives types can be used. From this document,
A default value must be one of the following types of expressions:
a constant expression;
an expression of the form new ValType(), where ValType is a value
type, such as an enum or a struct;
an expression of the form default(ValType), where ValType is a value
type.
The "primitives" list link above has been modified for 2010 to be called "built-in" types. It can be found here.
A default parameter value must be a compile time constant, so you can't do this.
You can't use initializers as default.
You could use:
private static void diagonalFill(int[,] a,
int[] fillType = null,
int[] diagFill = null)
{
if (fillType == null)
fillType = new int[] {0,-1};
if (diagFill == null)
diagFill = new int[] {-1,1};
...
}
I want to create a new type, i. e:
[sbyte (1 Byte) Value-range : -128 to +127]
[byte (1 Byte) Value-range : 0 to +255]
[short (2 Byte) Value-range : -32768 to +32767]
[ushort (2 Byte) Value-range : 0 to +65535]
[int (4 Byte) Value-range : -2147483648 to +2147483647]
[uint (4 Byte) Value-range : 0 to +4294967295]
.
.
.
etc.
now I want to create LInt(LowInt) Type in range 0 to 200000, so I dont want to use uint or int.
Is it any possible with C#?
Thank You!
Yes, that is what classes are for. Now, you cannot create a new "builtin" type. The semantics may not be exactly the same, but I'm guessing you won't care too much about those differences.
It is not possible in a built-in way, using simple language, e.g. int<5000,20000>.
While it is possible with a more complex definition, it isn't easy. It is difficult to determine and define all the semantics you'd want, such as:
Conversion to other ranged types
Conversion from built in numeric types
What should happen on overflow/underflow
What should the resulting type's range be after arithmetic is performed
Such a solution also wouldn't cover cases where you'd want one parameter's type range be constrained based on another parameter's value.
An alternative would be to use something like Code Contracts to define contracts for your code so you can do arbitrary static (compile time) verifications.
Edit: Removed link to SpecSharp. It looks like it was replaced with Code Contracts...
you can also use a struct to create a "type", but you are not able to create a primitive type.
You can create an object and handle your conditions, if you want it to act more like a primitive try making it a struct
It is of no use. Your CPU architecture defines what chunks of data it can handle at once and for what purposes. Even if you created a type that only allowed for different min-max values (which you can implement in a class and operator overloading), it would not be more efficient in neither memory nor performance aspects.
If you want to simply enforce some semantics, here's something that should lead in you the right direction (it's by no means complete, and lacks support for the checked and unchecked keywords).
struct MyInt
{
static uint max = 200000;
readonly uint i;
public MyInt(uint i) {
this.i = i;
}
public static implicit operator MyInt(uint j) {
if(j > max)
throw new ArgumentException();
return new MyInt(j);
}
public static MyInt operator +(MyInt i, uint j) {
try {
return new MyInt(i.i + j);
}
catch(ArgumentException) {
throw new OverflowException();
}
}
public override string ToString ()
{
return i.ToString();
}
}
This question already has answers here:
Should you declare methods using overloads or optional parameters in C# 4.0?
(13 answers)
Closed 9 years ago.
which one is better? at a glance optional parameter seems better (less code, less XML documentation, etc), but why do most MSDN library classes use overloading instead of optional parameters?
Is there any special thing you have to take note when you choose to use optional parameter (or overloading)?
One good use case for 'Optional parameters' in conjunction with 'Named Parameters' in C# 4.0 is that it presents us with an elegant alternative to method overloading where you overload method based on the number of parameters.
For example say you want a method foo to be be called/used like so, foo(), foo(1), foo(1,2), foo(1,2, "hello"). With method overloading you would implement the solution like this,
///Base foo method
public void DoFoo(int a, long b, string c)
{
//Do something
}
/// Foo with 2 params only
public void DoFoo(int a, long b)
{
/// ....
DoFoo(a, b, "Hello");
}
public void DoFoo(int a)
{
///....
DoFoo(a, 23, "Hello");
}
.....
With optional parameters in C# 4.0 you would implement the use case like the following,
public void DoFoo(int a = 10, long b = 23, string c = "Hello")
Then you could use the method like so - Note the use of named parameter -
DoFoo(c:"Hello There, John Doe")
This call takes parameter a value as 10 and parameter b as 23.
Another variant of this call - notice you don't need to set the parameter values in the order as they appear in the method signature, the named parameter makes the value explicit.
DoFoo(c:"hello again", a:100)
Another benefit of using named parameter is that it greatly enhances readability and thus code maintenance of optional parameter methods.
Note how one method pretty much makes redundant having to define 3 or more methods in method overloading. This I have found is a good use case for using optional parameter in conjunction with named parameters.
Optional Parameters provide issues when you expose them publicly as API. A rename of a parameter can lead to issues. Changing the default value leads to issues (See e.g. here for some info: Caveats of C# 4.0 optional parameters)
Also, optional params can only be used for compile-time constants. Compare this:
public static void Foo(IEnumerable<string> items = new List<string>()) {}
// Default parameter value for 'items' must be a compile-time constant
to this
public static void Foo() { Foo(new List<string>());}
public static void Foo(IEnumerable<string> items) {}
//all good
Update
Here's some additional reading material when a constructor with default parameters does not play nicely with Reflection.
I believe they serve different purposes. Optional parameters are for when you can use a default value for a parameter, and the underlying code will be the same:
public CreditScore CheckCredit(
bool useHistoricalData = false,
bool useStrongHeuristics = true) {
// ...
}
Method overloads are for when you have mutually-exclusive (subsets of) parameters. That normally means that you need to preprocess some parameters, or that you have different code altogether for the different "versions" of your method (note that even in this case, some parameters can be shared, that's why I mentioned "subsets" above):
public void SendSurvey(IList<Customer> customers, int surveyKey) {
// will loop and call the other one
}
public void SendSurvey(Customer customer, int surveyKey) {
...
}
(I wrote about this some time ago here)
This one almost goes without saying, but:
Not all languages support optional parameters. If you want your libraries to be friendly to those languages, you have to use overloads.
Granted, this isn't even an issue for most shops. But you can bet it's why Microsoft doesn't use optional parameters in the Base Class Library.
Neither is definitively "better" than the other. They both have their place in writing good code. Optional parameters should be used if the parameters can have a default value. Method overloading should be used when the difference in signature goes beyond not defining parameters that could have default values (such as that the behavior differs depending on which parameters are passed, and which are left to the default).
// this is a good candidate for optional parameters
public void DoSomething(int requiredThing, int nextThing = 12, int lastThing = 0)
// this is not, because it should be one or the other, but not both
public void DoSomething(Stream streamData = null, string stringData = null)
// these are good candidates for overloading
public void DoSomething(Stream data)
public void DoSomething(string data)
// these are no longer good candidates for overloading
public void DoSomething(int firstThing)
{
DoSomething(firstThing, 12);
}
public void DoSomething(int firstThing, int nextThing)
{
DoSomething(firstThing, nextThing, 0);
}
public void DoSomething(int firstThing, int nextThing, int lastThing)
{
...
}
Optional parameters has to be last. So you can not add an extra parameter to that method unless its also optional. Ex:
void MyMethod(int value, int otherValue = 0);
If you want to add a new parameter to this method without overloading it has to be optional. Like this
void MyMethod(int value, int otherValue = 0, int newParam = 0);
If it can't be optional, then you have to use overloading and remove the optional value for 'otherValue'. Like this:
void MyMethod(int value, int otherValue = 0);
void MyMethod(int value, int otherValue, int newParam);
I assume that you want to keep the ordering of the parameters the same.
So using optional parameters reduces the number of methods you need to have in your class, but is limited in that they need to be last.
Update
When calling methods with optional parameters, you can used named parameters like this:
void MyMethod(int value, int otherValue = 0, int newValue = 0);
MyMethod(10, newValue: 10); // Here I omitted the otherValue parameter that defaults to 0
So optional parameters gives the caller more possibilities.
One last thing. If you use method overloading with one implementation, like this:
void MyMethod(int value, int otherValue)
{
// Do the work
}
void MyMethod(int value)
{
MyMethod(value, 0); // Do the defaulting by method overloading
}
Then when calling 'MyMethod' like this:
MyMethod(100);
Will result in 2 method calls. But if you use optional parameters there is only one implementation of 'MyMethod' and hence, only one method call.
What about a 3rd option: pass an instance of a class with properties corresponding to various "optional parameters".
This provides the same benefit as named and optional parameters, but I feel that this is often much clearer. It gives you an opportunity to logically group parameters if necessary (i.e. with composition) and encapsulate some basic validation as well.
Also, if you expect clients that consume your methods to do any kind of metaprogramming (such as building linq expressions involving your methods), I think that keeping the method signature simple has its advantages.
A good place to use optional parameter is WCF since it does not support method overloading.
This is not really an answer to the original question, but rather a comment on #NileshGule's answer, but:
a) I don't have enough reputation points to comment
b) Multiple lines of code is quite hard to read in comments
Nilesh Gule wrote:
One benefit of using optional parameters is that you need not have to do a conditional check in your methods like if a string was null or empty if one of the input parameter was a string. As there would be a default value assigned to the optional parameter, the defensive coding will be reduced to a great extent.
This is actually incorrect, you still have to check for nulls:
void DoSomething(string value = "") // Unfortunately string.Empty is not a compile-time constant and cannot be used as default value
{
if(value == null)
throw new ArgumentNullException();
}
DoSomething(); // OK, will use default value of ""
DoSomething(null); // Will throw
If you supply a null string reference, it will not be replaced by the default value. So you still need to check the input parameters for nulls.
To address your first question,
why do most MSDN library classes use
overloading instead of optional
parameters?
It is for backward compatibility.
When you open a C# 2, 3.0 or 3.5 project in VS2010, it is automatically upgraded.
Just imagine the inconvenience it would create if each of the overloads used in the project had to be converted to match the corresponding optional parameter declaration.
Besides, as the saying goes, "why fix what is not broken?". It is not necessary to replace overloads that already work with new implementations.
One benefit of using optional parameters is that you need not have to do a conditional check in your methods like if a string was null or empty if one of the input parameter was a string. As there would be a default value assigned to the optional parameter, the defensive coding will be reduced to a great extent.
Named parameters give the flexibility of passing parameter values in any order.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Cast int to enum in C#
If I have the following code:
enum foo : int
{
option1 = 1,
option2,
...
}
private foo convertIntToFoo(int value)
{
// Convert int to respective Foo value or throw exception
}
What would the conversion code look like?
It's fine just to cast your int to Foo:
int i = 1;
Foo f = (Foo)i;
If you try to cast a value that's not defined it will still work. The only harm that may come from this is in how you use the value later on.
If you really want to make sure your value is defined in the enum, you can use Enum.IsDefined:
int i = 1;
if (Enum.IsDefined(typeof(Foo), i))
{
Foo f = (Foo)i;
}
else
{
// Throw exception, etc.
}
However, using IsDefined costs more than just casting. Which you use depends on your implemenation. You might consider restricting user input, or handling a default case when you use the enum.
Also note that you don't have to specify that your enum inherits from int; this is the default behavior.
I'm pretty sure you can do explicit casting here.
foo f = (foo)value;
So long as you say the enum inherits(?) from int, which you have.
enum foo : int
EDIT Yes it turns out that by default, an enums underlying type is int. You can however use any integral type except char.
You can also cast from a value that's not in the enum, producing an invalid enum. I suspect this works by just changing the type of the reference and not actually changing the value in memory.
enum (C# Reference)
Enumeration Types (C# Programming Guide)
Casting should be enough. If you're using C# 3.0 you can make a handy extension method to parse enum values:
public static TEnum ToEnum<TInput, TEnum>(this TInput value)
{
Type type = typeof(TEnum);
if (value == default(TInput))
{
throw new ArgumentException("Value is null or empty.", "value");
}
if (!type.IsEnum)
{
throw new ArgumentException("Enum expected.", "TEnum");
}
return (TEnum)Enum.Parse(type, value.ToString(), true);
}
if (Enum.IsDefined(typeof(foo), value))
{
return (Foo)Enum.Parse(typeof(foo), value);
}
Hope this helps
Edit
This answer got down voted as value in my example is a string, where as the question asked for an int. My applogies; the following should be a bit clearer :-)
Type fooType = typeof(foo);
if (Enum.IsDefined(fooType , value.ToString()))
{
return (Foo)Enum.Parse(fooType , value.ToString());
}
You don't need the inheritance. You can do:
(Foo)1
it will work ;)