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;
}
Related
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.
I'm having trouble iterating over all possible combinations of enums. I'm not too familiar with them as I've just started C# and am coming in from low level languages like C and assembler.
public enum enumA { A1, A2, A3 }
public enum enumB { B1, B2, B3 }
public class foo
{
private enumA enumAfoo;
private enumB enumBfoo;
public foo()
{
}
public foo(enumA A, enumB B)
{
enumAfoo = A;
enumBfoo = B;
}
}
public class fooTwo
{
private List<foo> allCombinations = new List<foo>();
public fooTwo()
{
}
public List<foo> GetList()
{
return allCombinations;
}
public fooTwo(bool check)
{
if (check)
{
foreach (enumA i in Enum.GetValues(typeof(enumA)))
{
foreach (enumB j in Enum.GetValues(typeof(enumB)))
{
allCombinations.Add(new foo(i, j));
}
}
}
}
}
When I run this code in a simple check output, I don't get what I'm after. Sample Main below. The output I get is just "TestingGround.foo" repeated 6 times, testing ground being my overall namespace. I Don't know if there's a problem with my logic of instantiating the list, or with how I'm converting it to string and outputting but I'd very much like some help in what's the correct procedure for doing this.
class Program
{
static void Main(string[] args)
{
fooTwo A = new fooTwo(true);
List<foo> list = A.GetList();
foreach (foo j in list)
{
Console.WriteLine(j.ToString());
}
Console.ReadKey();
}
}
ToString() returns a default representation of the object. You need to create your own ToString() method, returning what you need. For example:
public class foo
{
private enumA enumAfoo;
private enumB enumBfoo;
public foo()
{
}
public foo(enumA A, enumB B)
{
enumAfoo = A;
enumBfoo = B;
}
public override string ToString()
{
return enumAfoo.ToString() + "," + enumBfoo.ToString();
}
}
Please keep in mind that Enum has the Integer underlying value (btw, it must be unique: you can get it with simple (int) type casting). So, you are essentially have the values: 0, 1, 2 in each enum. Now, the unique combinations based on string concatenation are: 00, 01, 02, 10,11, 12, 20, 21, 22. Is it what you are looking for? Otherwise, you can apply "+" operator on underlying int values (but it will produce just 5 unique values).
Another scenario would be a concatenation of strings: you should use ToString() method in this case to get the combinations (assuming "+" operator applied to strings) of those "A1", "B1", etc. Also, you can use String.Concat(enum1, enum2) method as a shortcut; in this case you can omit the ToString()because String.Concat() will take care of proper type casting to string.
Hope this may help. Best regards,
Suppose in a C# class there is a method Like _Abc(int a, int b) usually it takes 2 parameters.
Is it possible to get 4 int values from _Abc(int a, int b) method as return?
You could return a Tuple<int, int, int, int>. Returning tuples as part of a public API isn't very informative however, so in that case I would create a class to hold the return values so you can name the values.
Though the answers so far (return a tuple, return a collection, return a custom class/struct, or use out parameters) are reasonable answers, a better answer is: don't do that in the first place. A method that returns four things is probably a badly-designed method.
Can you redesign the type so that you have, say, four different methods (or properties) each of which returns one thing? There may be a better pattern for you to use. Can you explain your scenario in more detail?
You can return a custom type which is the most flexible and extensible approach.
public static Foo GetFoo(int a, int b)
{
Foo foo = new Foo();
foo.A = 1;
foo.B = 2;
foo.C = 3;
foo.D = 4;
return foo;
}
Here's the pseudo class
public class Foo
{
public int A{ get; set; }
public int B{ get; set; }
public int C{ get; set; }
public int D{ get; set; }
}
Another way (with .NET 4) is using a Tuple
public static Tuple<int,int,int,int> GetFoo(int a, int b)
{
return Tuple.Create(1,2,3,4);
}
Which is not so readable as the class approach since you read the properties in this way:
var values = GetFoo(1, 2);
int A = values.Item1;
int B = values.Item2;
int C = values.Item3;
int D = values.Item4;
So a tuple is somehwhat anonymous.
If you just want to return one or two additional parameters you can also use an out parameter as in the TryParse methods.
DateTime dt;
String str = "01.01.2013";
if(DateTime.TryParse(str, out dt))
{
// so this method returns two variables:
// a bool as return value and a DateTime as out parameter
Console.WriteLine("Year: " + dt.Year);
}
In addition to Lee's answer, You could add some ref or out parameters, ie:
_Abc(int a, int b, out int c, out int d, out int e, out int f)
You could also create a function like this with out parameters.
public void _Abc(int a, int b, out res1, out res2, out res3, out res4)
{
res1 = 1;
res2 = 2;
res3 = 3;
res4 = 4;
}
If you can change the method you can use out parameters. http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
_Abc(int a, int b, out int c, out int d, out int e, out int f){
c=1;
d=2;
e=3;
f=4;
}
You could return them as out parameters
If you're returning 4 completely different things, then it would be best to create a new type. For example, if you're returning the height, width, top, and bottom values of a newly created shape, then you should create a class that holds all of those values with the proper variable names.
If you're holding 4 of the same type of thing then it may make sense to put them all into a collection of some sort. For example, if the four numbers represent the area of four different shapes then it would make sense to return a List<int> or an int[].
I think you need easy ans, right?
Try to understand this simple code (just copy and paste):
class Class1
{
private List<int> _Abc(int a, int b)
{
// do job
int x = 128, y = 256, z = 512;
List<int> returns = new List<int>();
returns.Add(x);
returns.Add(y);
returns.Add(z);
return returns;
}
public void anotherMethod()
{
List<int> simple = new List<int>();
simple = _Abc(55, 56);
int[] _simple = simple.ToArray();
for (int i = 0; i < simple.Count; i++)
{
Console.WriteLine("" + _simple[i]);
}
//Console.ReadKey();
}
}
I have an array of structs, where the struct has three integer fields. It is sorted by one of the fields, say F, and I want a way to do a binary search with respect to this field, that is, a function of the form binarySearch(mystruct[] myarray, int val) which returns the index of the structure in which field F = val. I know that there is an existing Array.BinarySearch(T[] array, T value) function, but it only allows to search for a type T that is the same as the types in the array. This means that if I want to search with respect to a value, I need to create a new struct and set field F to that value just so that I can pass it to this function. I don't think there would be significant performance overhead but it seems ugly. The other way I can think is to implement the function myself, but this also seems inelegant when something so similar exists. Any suggestions for a better way or which way would be preferred?
You can either implement IComparable<T> for your struct to compare on the field (F), or you can create an IComparer<> for your struct that will compare based on that field and pass that into Array.BinarySearch().
So either:
// using IComparable<T>
public struct MyStruct : IComparable<MyStruct>
{
public int F { get; set; }
// other fields that should not affect "search"
public int X { get; set; }
public int CompareTo(MyStruct other)
{
return F.CompareTo(other.F);
}
}
Which can be called as:
MyStruct target = new MyStruct { F = 13 };
Array.BinarySearch(arrayOfMyStruct, target);
Or a separate IComparer<MyStruct>:
public struct MyStruct
{
public int F { get; set; }
// other non-sort/search affecting properties
public int X { get; set; }
}
public struct MyStructComparer : IComparer<MyStruct>
{
public int Compare(MyStruct x, MyStruct y)
{
return x.F.CompareTo(y.F);
}
}
Which can be called like:
MyStruct target { F = 13; }
Array.BinarySearch(myArrayOfStruct, target, new MyStructComparer());
The first has less code, but it strongly couples ordering to the type, which if you want to alter ordering based on situation (that is, allow multiple sort orders), this isn't ideal. The latter gives more flexibility in that you can provide multiple different orders independent of the struct, but it does require an extra class.
UPDATE
If you don't want to create a dummy struct to compare against, you can implement IComparable like:
public struct MyStruct : IComparable
{
public int F { get; set; }
// other non-sort/search affecting properties
public int X { get; set; }
public int CompareTo(object other)
{
// if the type is NOT an int, you can decide whether you'd prefer
// to throw, but the concept of comparing the struct to something
// unknown shouldn't return a value, should probably throw.
return F.CompareTo((int)other);
}
}
Which could be called like:
Array.BinarySearch(arrayOfMyStruct, 13);
But again, this strongly ties your implementation of the class to a given comparison type, which I think is uglier than using a dummy search target, but that's my personal preference. Personally, especially with initializer syntax being as short as it is, I prefer to use the dummy target:
var target = new MyStruct { F = 13 };
UPDATE: You can support both int and MyStruct comparissons, but it gets messy quickly, which is why I personally, again, recommend using the dummy struct to avoid the headaches:
// implement IComparable<int> for the int search (w/o dummy), and IComparable<MyStruct> for sort
public struct MyStruct : IComparable, IComparable<MyStruct>, IComparable<int>
{
public int F { get; set; }
// other non-sort/search affecting properties
public int X { get; set; }
public int CompareTo(object other)
{
if (other is int)
return F.CompareTo((int)other);
if (other is MyStruct)
return F.CompareTo((MyStruct)other);
throw new InvalidOperationException("Other must be int or MyStruct.");
}
public int CompareTo(MyStruct other)
{
return F.CompareTo(other.F);
}
public int CompareTo(int other)
{
return F.CompareTo(other);
}
}
If your struct implements IComparable, you can use:
// myValue is an the value of the field to compare to
Array.BinarySearch(myArray, myValue);
as described in http://msdn.microsoft.com/en-us/library/y15ef976.aspx
You can compare a struct to an object with IComparable, so you can pass in the value intead of a new struct. In your implementation of CompareTo, you can compare any value with the field value, allowing you to say 'My struct should be considered greater/less than this number'.
EDIT:
Here is an example of CompareTo for your struct:
public int CompareTo(object obj)
{
if (obj is int)
{
return myIntField.CompareTo((int)obj);
}
return 0;
}
One way would be to create a custom IComparer<T> that compares instances of your struct based only on the value of that field and pass it to this overload of BinarySearch (you will also need to create a "dummy" struct instance to compare to). This is probably the purest solution.
However, as a practical matter you can use LINQ to project into a collection of field values and binary search into that; the resulting index will be the same as if you had searched the struct collection itself. For example:
var structs = new MyStruct[n];
var index = structs.Select(i => i.F).ToList().BinarySearch(42);
In the code above, F is the vame of the field and 42 is the value you are searching for (its type would be the type of F). This is not going to be as fast, but you don't need to write any code and speed could very well be irrelevant in your case.
Update: To clarify: obviously, the code above will be O(n) due to the projection operation so using binary search once after projecting like that is silly (you can simply do a linear search instead). However, if you intend to make multiple searches then it might start making sense.
I would definitely not recommend overriding Equals in your struct unless comparisons between instances are meant to be reduced to comparing F members everywhere in your application.
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