Hii
I have method in C#, I have to return multiple values from that method with out using collections like arrays. Is there any reliable way ?
Yes, the out keyword:
public void ReturnManyInts(out int int1, out int int2, out int int3)
{
int1 = 10;
int2 = 20;
int3 = 30;
}
then call it like this:
int i1, i2, i3;
ReturnManyInts(out i1, out i2, out i3);
Console.WriteLine(i1);
Console.WriteLine(i2);
Console.WriteLine(i3);
which outputs:
10
20
30
EDIT:
I'm seeing that a lot of posts are suggesting to create your own class for this. This is not necessary as .net provides you with a class to do what they are saying already. The Tuple class.
public Tuple<int, string, char> ReturnMany()
{
return new Tuple<int, string, char>(1, "some string", 'B');
}
then you can retrieve it like so:
var myTuple = ReturnMany();
myTuple.Item1 ...
myTuple.Item2 ...
there are generic overloads so you can have up to 8 unique types in your tuple.
Well, you could use:
a custom class/struct/type, containing all your values
out parameters
I.e.:
class MyValues
{
public string Val1 { get; set; }
public int Val2 {get; set; }
}
public MyValues ReturnMyValues();
or
public void ReturnMyValues(out string Val1, out int Val2);
If you are using .NET 4.0 you can use one of the generic Tuple classes to return multiple values from a method call. The static Tuple class provides methods to create Tuple objects. So you do not have to define your own return type for the method.
public Tuple<string,int> Execute()
{
return new Tuple<string,int>("Hello World", 2);
}
Yes could create a new type that will contain multiple properties and then return this type:
public MyType MyMethod()
{
return new MyType
{
Prop1 = "foo",
Prop2 = "bar"
};
}
Why should using 'out' being an unreliable way? (Or did you make a typo and meant without?)
There are several methods:
Return a object which holds multiple
values (struct/class etc)
out
ref
A Descriptor class, or structure. You must put it somewhere as it's logical that a method must return only one value. Alternatively you can use out or ref, but i would go returning a class.
Btw what's holding you not to use collections?.
public int Method Name(out string stringValue, out int intValue)
{
///
Method goes here
///
return intVaraible
}
here you will get 3 return Values
1. stringValue
2. intValue
3. intVariable
Related
I'm trying to make default value for my struct.
For example default value for Int - 0, for DateTime - 1/1/0001 12:00:00 AM.
As known we can't define parameterless constructor in structure.
struct Test
{
int num;
string str;
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(default(Test)); // shows namespace and name of struct test.Test
Console.WriteLine(new Test()); // same
Console.ReadKey(true);
}
}
How can I make a default value for struct?
You can't. Structures are always pre-zeroed, and there is no guarantee the constructor is ever called (e.g. new MyStruct[10]). If you need default values other than zero, you need to use a class. That's why you can't change the default constructor in the first place (until C# 6) - it never executes.
The closest you can get is by using Nullable fields, and interpreting them to have some default value if they are null through a property:
public struct MyStruct
{
int? myInt;
public int MyInt { get { return myInt ?? 42; } set { myInt = value; } }
}
myInt is still pre-zeroed, but you interpret the "zero" as your own default value (in this case, 42). Of course, this may be entirely unnecessary overhead :)
As for the Console.WriteLine, it simply calls the virtual ToString. You can change it to return it whatever you want.
Your problem is not with the behaviour of C#/.Net. The way you instantiate the struct effectively creates an instance with default values for all member fields.
The Console.WriteLine converts its argument to a string using the ToString() method. The default implementation (Object.ToString()) simply writes the fully qualified class name (namespace and name, as you call it).
If you want another visualisation, you should override the ToString method:
public struct Test
{
int num;
string str;
public override string ToString()
{
return $"num: {num} - str: {str}";
}
}
This is my take on this in case somebody finds it useful.
public struct MyStruct
{
public int item1;
public float item2;
public float item3;
public static MyStruct Null => new MyStruct(-1, 0, 0);
}
I have a static method inside my struct so that I can do this:
var data = MyStruct.Null;
instead of
var data = new MyStruct();
data.item1 = -1;
...
Or create a custom constructor to pass the data.
Printing out objects of the C# results with namespaces unless you override .ToString() for your objects. Can you define your struct like below and try it ?
public struct Test
{
int num;
string str;
public override string ToString()
{
return "Some string representation of this struct";
}
}
PS: default(Test) gives you a struct contains default(int) and default(string) which I mean Test.num is 0 and Test.str is null
Hope this helps
You can also do this:
public struct MyStruct
{
public static readonly Default = new MyStruct(42);
public int i;
public MyStruct(int i)
{
this.i = i;
}
}
And then when you create a default struct of this type do this:
public MyStruct newStruct = MyStruct.Default;
But of course, this won't override default and other programmers will bump their heads a few times. Really consider if a struct is the way to go, from the microsoft docs:
"A structure type (or struct type) is a value type that can encapsulate data and related functionality. Typically, you use structure types to design small data-centric types that provide little or no behavior."
Consider this: if you had 2 values in your struct and you wanted to make constructors, would 2 or less constructors suffice? If the answer is no, then the answer is: don't use a struct.
What you probably want to do is to override ToString(), e.g.
struct Test
{
int num;
string str;
public override string ToString ()
{
return string.Format ($"{str} | {num}");
}
}
As you have mentioned, it is impossible to define default values for fields other than default values for their appropriate types. However, with an overriden ToString(), you will see better formatted information about your structure in the console and during debugging.
This question already has answers here:
Return multiple values to a method caller
(28 answers)
Closed 3 years ago.
I have a method like this:
private double GetHeight()
{
return 2;
}
But I would like to be able to return two different numbers for example 2 and 3. Is there any way that I can do this in C#?
Yes ValueTuple / Named Tuple (available in C# 7.0). The advantage is it's the most succinct, it's immutable, and it's easy to construct.
The ValueTuple struct has fields named Item1, Item2, Item3, and so on,
similar to the properties defined in the existing Tuple types.
However, when you initialize a tuple, you can use new language
features that give better names to each field. Doing so creates a
named tuple. Named tuples still have elements named Item1, Item2,
Item3 and so on. But they also have synonyms for any of those elements
that you have named. You create a named tuple by specifying the names
for each element.
private (double first, double second) GetHeight()
{
return (1,2);
}
...
var result = ViaNamedValueTuple();
Console.WriteLine($"{result.first}, {result.second}");
var (first, second) = ViaNamedValueTuple();
Console.WriteLine($"{first}, {second}");
Classic Tuple
C# tuple type
The .NET Framework already has generic Tuple classes. These classes,
however, had two major limitations. For one, the Tuple classes named
their properties Item1, Item2, and so on. Those names carry no
semantic information. Using these Tuple types does not enable
communicating the meaning of each of the properties. The new language
features enable you to declare and use semantically meaningful names
for the elements in a tuple.
public Tuple<int, int> ViaClassicTuple()
{
return new Tuple<int, int>(1,2);
}
...
var tuple = ViaClassicTuple();
Console.WriteLine($"{tuple.Item1}, {tuple.Item2}");
Classic struct
struct (C# Reference)
A struct type is a value type that is typically used to encapsulate
small groups of related variables, such as the coordinates of a
rectangle or the characteristics of an item in an inventory.
public struct ClassicStruct
{
public int First { get; set; }
public int Second { get; set; }
public ClassicStruct(int first, int second)
{
First = first;
Second = second;
}
}
...
public ClassicStruct ViaClassicStruct()
{
return new ClassicStruct(1, 2);
}
...
var classicStruct = ViaClassicStruct();
Console.WriteLine($"{classicStruct.First}, {classicStruct.Second}");
Readonly struct
readonly (C# Reference)
The readonly modifier on a struct definition declares that the struct
is immutable. Every instance field of the struct must be marked
readonly, as shown in the following example:
public readonly struct ReadonlyStruct
{
public int First { get; }
public int Second { get; }
public ReadonlyStruct(int first, int second)
{
First = first;
Second = second;
}
}
...
public ReadonlyStruct ViaReadonlyStruct()
{
return new ReadonlyStruct(1, 2);
}
...
var readonlyStruct = ViaReadonlyStruct();
Console.WriteLine($"{readonlyStruct.First}, {readonlyStruct.Second}");
Simple Class
Classes (C# Programming Guide)
A type that is defined as a class is a reference type. At run time,
when you declare a variable of a reference type, the variable contains
the value null until you explicitly create an instance of the class by
using the new operator, or assign it an object of a compatible type
that may have been created elsewhere
public class SomeClass
{
public int First { get; set; }
public int Second { get; set; }
public SomeClass(int first, int second)
{
First = first;
Second = second;
}
}
...
public SomeClass ViaSomeClass()
{
return new SomeClass(1, 2);
}
...
var someClass = ViaSomeClass();
Console.WriteLine($"{someClass.First}, {someClass.Second}");
Out parameters
out parameter modifier (C# Reference)
The out keyword causes arguments to be passed by reference. It makes
the formal parameter an alias for the argument, which must be a
variable. In other words, any operation on the parameter is made on
the argument. It is like the ref keyword, except that ref requires
that the variable be initialized before it is passed. It is also like
the in keyword, except that in does not allow the called method to
modify the argument value. To use an out parameter, both the method
definition and the calling method must explicitly use the out keyword.
public bool ViaOutParams(out int first, out int second)
{
first = 1;
second = 2;
return someCondition;
}
...
if(ViaOutParams(out var firstInt, out var secondInt))
Console.WriteLine($"{firstInt}, {secondInt}");
Out Value Tuple
public bool ViaOutTuple(out (int first,int second) output)
{
output = (1, 2);
return someCondition;
}
...
if (ViaOutTuple(out var output))
Console.WriteLine($"{output.first}, {output.second}");
Multiple ways:
out parameters:
private double GetHeight(out int anotherValue)
{
anotherValue = 42;
return 2;
}
value-tuples:
private (double height, int anotherValue) GetHeight()
{
return (42, 2);
}
(warning: value-tuples have known problems if used in .NET Standard libraries, as the assembly bindings from .NET Standard to .NET Framework are ... kinda fubar)
custom return types:
private Something GetHeight()
{
return new Something(42, 2);
}
(to avoid allocations, you may wish to define Something as a readonly struct in this scenario)
Yes, you can use Tuple:
class Program
{
static void Main(string[] args)
{
Tuple<int, int> height = GetHeight();
Console.WriteLine(height.Item1 + " - " + height.Item2);
Console.ReadLine();
}
private static Tuple<int, int> GetHeight()
{
return new Tuple<int, int>(2, 3);
}
}
OUTPUT:
2 - 3
Also you could use out parameters:
static void Main(string[] args)
{
int i, j;
GetHeight(out i, out j);
}
public static void GetHeight(out int i1, out int i2)
{
i1 = 1;
i2 = 2;
}
Make a int array.Or another way is to create class.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I return multiple values from a function in C#?
C# methods is always like this:
public <return type> funName()
{
//do sth
return someValueformatedasReturnType;
}
how to return 2 values from 1 c# methods?
This is a interview question, as many as you know. Thanks!
From best to worst (IMHO):
Create a new class for the return type
Use a Tuple
Use out parameters
You have a few options:
output parameters
Tuple
Class that has 2 properties
you can use the ref or out keyword for your function parameters.
int i;
int j;
dosomething(out i, out j);
public void dosomething(out int a, out int b)
{
a = 1;
b = 2;
}
after calling the function, i = 1, j = 2. same for ref keyword, msdn tells the difference :)
or return a tuple.
#tudor
look at your names, using out as object name :S, out is used to pass value by reference!
Define a new data type (Class) with the two outputs:
public class Output
{
public object Val1 { get; set; }
public object Val2 { get; set; }
}
and return a new object of type Output:
public Output FunName()
{
Output out = new Output;
out.Val1 = val1;
out.Val2 = val2;
return out;
}
This is for a mathematical method that takes in 3 doubles as input (a, b,c ).
Next those 3 values get calculated in a formula (abc formula for square roots).
The formula has 2 values that have to be returned but how exactly do i do this?
I was thinking of a array / objects, but not sure how to initialise them for this purpose. Out parameters are not really of any use in this situation are they?
Regards.
In C# 4 (available in Visual Studio 2010):
Tuple<double, double> Foo(double a, double b, double c)
{
...
return Tuple.Create(firstReturnValue, secondReturnValue);
}
If you're working with an earlier language version of C#, you can define your own implementation of a two-tuple (pair) as follows:
public struct Tuple<A, B>
{
public readonly A Item1;
public readonly B Item2;
public Tuple(A a, B b) { Item1 = a; Item2 = b; }
}
public static class Tuple
{
public static Tuple<A,B> Create<A,B>(A a, B b) { return new Tuple<A,B>(a,b); }
}
Of course, Tuple is a very general and unspecific data type. You could just as well implement a composite return type (similar to what I just showed, but simpler) that is more specific to your situation.
Use out:
double t;
int y = Foo(5,3,out t);
def:
public int Foo(int one,int two,out double three) {
three = one / two;
return one + two;
}
http://msdn.microsoft.com/en-us/library/ee332485.aspx
In C# 4 , you can do same as Tuple as described by staks above
but below c#4 , you can return a list which contains as many as values you want to return.
I'd create a class for the purpose, of even a simple struct, but a Tuple (like stakx suggested) is just as good, and even a list or a collection can do the trick.
An array is not very favorable, since you just have a bunch of items, without any further information about them, really. The caller has to somehow "know" what element no. 0, element no. 1 is.
In such a case, I would always vote for using a class - define a return type as a class, give the individual fields meaningful names. A class gives you discoverability (through field names), the ability to mix the return types (return an INT, two DECIMAL, a STRING), and it nicely encapsulates your results:
public class ResultType
{
decimal Value { get; set; }
decimal AnotherValue { get; set; }
int StatusCode { get; set; }
string Message { get; set; }
}
and then define your method as:
ResultType YourMethodName(double a, double b, double c)
{
ResultType result = new ResultType();
// do your calculations here......
result.Value = .........
result.AnotherValue = ............
result.StatusCode = 0;
result.Message = "everything OK";
return result;
}
I have code similar to the following in many places:
var dbParams = db.ReadParams(memberID, product, GetSubscriptionFields());
Debug.Assert(dbParams.Count == 4);
_memberCode = dbParams[0];
_password = dbParams[1];
_userName = dbParams[2];
_reasonCode = dbParams[3];
ReadParams() returns an array of strings, the number of strings depending on the GetSubscriptionFields() function. I could use dbParams[] directly in my code, but I find it more helpful to give meaningful names to each of the values in the array. Is there a way I can get all the results directly, without going through the array?
I am looking for something like:
db.ReadParams(memberID, product, out _memberCode, out _password, out _userName, out _reasonCode);
or
Tuple<_memberCode, _password, _userName, _reasonCode> = db.ReadParams(memberID, product);
Of course, it has to be legal C# code :)
You are writing code in a highly object oriented language, so why don't you use objects?
Member m = db.ReadParams(memberID, product, GetSubscriptionFields());
and in your code you use
m.memberCode
m.password
m.username
m.reasonCode
Of course you don't have to make the values publicly accessible, you can make them only accessible via setter/getter methods, and by only having getters, you can avoid them from being altered after object creation.
Of course different calls to db.ReadParams should return different objects, e.g. you can create an abstract base class and inherit all possible results from db.ReadParams of it. Therefor you may have to encapsulate db.ReadParams into another method that finds out the right type of object to create:
ReadParamsResult rpr = myDb.ReadParamsAsObject(memberID, product, GetSubscriptionFields());
// Verify that the expected result object has been returned
Debug.Assert(rpr is Member);
// Downcast
Member m = (Member)rpr;
Why not use constants instead?
Then in your code you could have
dbParams[MEMBER_CODE]
dbParams[PASSWORD]
dbParams[USERNAME]
dbParams[REASON_CODE]
which meets your goal of meaningful names without changing the way the method works.
I think your Tuple idea is pretty good. You could define it like this:
public class Tuple<T1, T2, T3, T4>
{
public T1 Field1 { get; set; }
public T2 Field2 { get; set; }
public T3 Field3 { get; set; }
public T4 Field4 { get; set; }
}
You would probably want to define a few of those, with two and three properties. Unfortunately it doesn't help you naming the properties of the class. There really is no way to do that (at least not until C# 4.0, when you could use dynamic typing with an anonymous type.
Not really; since the number of arguments isn't fixed, there isn't really a better way of doing it. The problem with regular tuples is that you are still working positionally - just with ".Value0" instead of "[0]". And anonymous types can't be directly exposed in an API.
Of course, you could subsequently wrap the values in your own class with properties, and just do a projection:
return new Foo {MemberCode = arr[0], ...}
(where Foo is your class that represents whatever this result is, with named, typed properties)
Alternatively you could throw them into a dictionary, but this doesn't help the caller any more than an array does.
The only other option is something really grungy like accepting a params array of Action<string> that you use to assign each. I'll elaborate on the last just for fun - I don't suggest you do this:
static void Main()
{
string name = "";
int value = 0;
Foo("whatever",
x => { name = x; },
x => { value = int.Parse(x); });
}
// yucky; wash eyes after reading...
static void Foo(string query, params Action<string>[] actions)
{
string[] results = Bar(query); // the actual query
int len = actions.Length < results.Length ? actions.Length : results.Length;
for (int i = 0; i < len; i++)
{
actions[i](results[i]);
}
}
I also came up with this... I kinda like it most, but it's a personal preference, I understand it's definitely not the cleanest idea:
using System.Diagnostics;
public static class ArrayExtractor
{
public static void Extract<T1>(this object[] array, out T1 value1)
where T1 : class
{
Debug.Assert(array.Length >= 1);
value1 = array[0] as T1;
}
public static void Extract<T1, T2>(this object[] array, out T1 value1, out T2 value2)
where T1 : class
where T2 : class
{
Debug.Assert(array.Length >= 2);
value1 = array[0] as T1;
value2 = array[1] as T2;
}
}
Of course, I am extending this class up to 10 or 15 arguments.
Usage:
string fileName;
string contents;
ArrayExtractor.Extract(args, out fileName, out contents);
or even better
args.Extract(out fileName, out contents);
where args is, of course, an object array.