C#, method that outputs multiple value - c#

I am using c#.
I have a method that outputs multiple values. I am aware of out but this is a reference type.
Is there anything equivalent to value type but that can also output multiple values from a method. With the reference type, the values are also changed outside of the method so I like to prevent.
out

I am aware of out but this is a reference type.
It's not clear what you mean. out isn't a type at all - it's a decorator for parameters. You can use it with reference types or value types:
// Nasty, but it does work...
void SplitInTwo(string input, out string x1, out string x2,
out int actualSplitCount)
{
string[] bits = input.Split('/');
x1 = bits[0];
x2 = bits[1];
actualSplitCount = bits.Length;
}
So you can use out either way. However, I would strongly advise you not to do so. You can use the Tuple family of types for ad hoc multiple values, but if the returned values are actually related, you should consider encapsulating them into a separate type, and returning a value of that type.

I'd recommend creating a class that describes your return value and has properties for each value you need to return.
Tuple is a decent option if you don't need to pass the result around often, but in general it's harder to maintain. I prefer working with meaningful property names rather than the Item1, Item2, Item3, etc. that Tuple provides. The out parameters also work, but they require the calling code to be written differently to accommodate the method implementation, which I recommend avoiding whenever possible.

Something along the lines of :
class MultiValue
{
type A {
get { return m_A; }
set { m_A = value; }
}
type B{
get { return m_B; }
set { m_B = value; }
}
private type m_A;
private type m_B;
}
Could work depending on what you're trying to do (Returns the value in a single instance or if you need to maintain those values over a period of time / methods).
But the Tuple types would also accomplish a similar effect, again, with better results depending what you want to do in your program.

The out keyword (and ref keyword) are used to indicate that a variable is provided from the caller's scope. They don't change the nature of the type in question.
out parameter modifier (C# Reference) # MSDN
If you're concerned requiring the caller being forced to specify out every time they use your method, you can use a Helper class or a Tuple to wrap the set of values returned.
Tuple Class # MSDN
You mention that you are concerned about reference-types being changed. This shouldn't be an issue to your method. The parameter specified by out is not shared by all cases where your method may used, they're local to the scope where your method is called. Only the caller needs to worry, and only in their own scope.
Last, if you want to indicate that a variable may be altered or used without being required to assign a value to it as out requires, use ref.

Related

In C# and ECMA-CIL, can a struct-instantiated generic be implemented using boxing?

ECMA-CIL allows generic instances to actually yield a different implementation of the generic definition when instantiated. The instantiation can be specialized based on the chosen generic arguments.
Is there any case where a generic may behave differently if instantiated by a struct instead of an object reference? This is a question regarding semantics; I am not talking about performance.
In other words, could a naive implementation of ECMA-CIL decide to implement struct-instantiated generics as boxed values (as in Java)?
I read ECMA-CIL, but I'm still not sure about this. Any feedback is more than appreciated. Although I'm particularly interested in what happens at the bytecode level, an answer from the C# language perspective is also valuable.
Here's a simulated boxed value type in C#:
public class Boxed<T> where T : struct
{
public T Value; // do not assign to!
public Boxed(T value) => Value = value;
}
This is the best we can do at .NET level, since there is no native way to make a boxed value type reference (C++/CLI uses a tagged object to specify that). This is also more or less equivalent to System.Runtime.CompilerServices.StrongBox<T>.
Is there any case where a generic may behave differently if instantiated by a struct instead of an object reference? This is a question regarding semantics; I am not talking about performance.
Of course, using Boxed<T> means that default(Boxed<T>) is null for example. Here is a situation where this could be an issue:
public static class GlobalVariable<T>
{
public T Value;
}
If .NET actually implemented GlobalVariable<int> using GlobalVariable<Boxed<int>>, the Value field would contain null instead of 0. A conforming CLI implementation would have to implicitly use Value = new Boxed<T>(default(T)); when the type is instantiated, or modify ldfld (or ldflda) to create such an instance there if there is null (wreaking havoc for threading and readonly).
Another issue is copy semantics of value types. Each opcode like ldloc or similar assumes that a value type would be copied and mutating the value of the target should not affect the source. For example:
public static class GlobalVariable<T>
{
public T Value;
public delegate void Mutator(ref T value);
public static T MutateCopy(Mutator mutator)
{
var copy = Value;
mutator(ref copy);
return copy;
}
}
Calling something like GlobalVariable<Boxed<ValueTuple<int>>>.MutateCopy would pose an issue (if the runtime actually translated mutator(ref copy) to something like mutator(ref copy.Value) in order to call the delegate) since it would access the same instance. The runtime would have to "clone" Value as an object during the assignment in order to fix it.
Summed up, a value type type argument *could* be implemented using boxing, but without any additional special treatment, you get the same issues you would get in Java when using wrapper classes. It could work without mutable value types or strict null conversion checks (and potentially without byref parameters), but anything more than that will require additional (and complicated) changes to the implementation or languages. For an example of such a thing, see "unboxed" reference types in C++/CLI (i.e. reference types without the hat ^, which have value semantics).

How can you change a variable inside a method and also change it outside

I have a variable that I want to change inside a function and reflex the new change in the orginal variable . I am trying to change the original variable value to Scott inside the function and then reflex that new change outside the function:
public ActionResult HomePage()
{
string name = "John";
ChangeName(name);
string newName = name ; -- This still says John
}
public static void ChangeName(string myname)
{
myname = "Scott";
}
You can do that by passing the string by reference -
public ActionResult HomePage()
{
string name = "John";
ChangeName(ref name);
string newName = name ; -- This is now Scott.
}
public static void ChangeName(ref string myname)
{
myname = "Scott";
}
However, as stated by TheSoftwareJedi in the comments, it is usually best to avoid passing parameters by reference. Instead, you should have your method return the new string, especially considering the fact that strings are immutable, so you can't really change them, you can only change the reference to point to another string.
So a better method would be something like this:
public static string GetAnotherName()
{
return "Scott";
}
A little more in depth - there are basically two kinds of types in c# (relevant to this point, at least): There are value types like enums, structs (including all primitive types such as int, bool etc') and there are reference types (basically, everything else).
Whenever you pass an argument to a method, it gets passed by value, unless you specify the ref (or out) keyword, even if it's a reference type (in that case, the reference gets passed by value). This means that when ever you are assigning a new value to the argument inside the method, you will only see it outside the method if the argument was passed explicitly by reference (using the ref or out keyword).
The main difference between reference types and value types is that when you change the properties of a reference type inside a method, you will see the new values outside the method as well, however when you change the properties of a value type inside a method, that change will not reflect to the variable outside that method.
Jon Skeet have written a fairly extensive article about that subject, and he is way better than me in explaining things, so you should probably read it as well.
To start with, I would recommend you to read about references, values and parameters passing. There is a nice summary on this theme by Jon Skeet — Parameter passing in C# and good explanation of reference concept by Eric Lippert — References are not addresses.
You should know that by default parameters are passed by value in C#, it means parameter will contain a copy of the reference passed as argument, it means assignments will only change parameter itself and won't be observable at the call site.
That's why
myname = "Scott";
Only changes value of the method parameter myname and not the outer name variable.
At the same time, we are able to pass our variable by reference with use of ref, in or out keywords. Although in and out keywords are adding excess guarantees, which are out of theme discussed, so I'll continue with ref.
You should change both declaration of your method and call site to use it.
public static void ChangeName(ref string myname)
{
myname = "Scott";
}
And it should be invoked now as
ChangeName(ref name);
This time there is no copying, so myname parameter stores the same reference as name variable and, moreover parameter and variable are stored at one location, it means changes to myname inside ChangeName method will be visible to invoking code.
To continue with, I'd like to point you to a separate, but related theme in regards of your question — Expressions and Statements and to link you to a good article about them written by Scott Wlaschin — Expressions vs statements (there is a bit of F# inside, but that's not critical).
Generally, there is nothing wrong with approach you've selected, but it's imperative, statement based and a bit too low level. You are forced to deal with references and their values, while what you really want is just to get value "Scott" from your method. This will look more straightforward and obvious, if implemented as an expression.
public static string GetName() => "Scott";
This way code is declarative and thus more simple (and short), it directly illustrates your goals.

Is there a benefit to using the c# out/ref keyword to "return" > 1 item in a method, instead of an object

Returning multiple things from a method, involves either:
returning an object with properties OR
using the out keyword to simply modify incoming parameters
Is there a benefit to using one system or the other? I have been using objects, but just discovered the out keyword, so wondering if I should bother refactoring.
You shouldn't bother refactoring just to utilize out parameters. Returning a class or struct would be preferred as long as structure is reusable.
A common use for out parameters which I would suggest using is to return a status for a call with that is possible to fail. An example being int.TryParse.
It has the possibility of failing, so returning a bool makes it easy to determing whether or not you should use the out parameter.
Another possible solution to returning multiple values from a method would be to use a Tuple. They can return n number of results. E.g.
public Tuple<bool, bool, string> MyMethod()
{
return new Tuple<bool, bool, string>(false, true, "yep");
}
In general, if the object that you are returning is not used anywhere else outside of the return value of your method or a group of similar methods, it is a good indication that you should refactor. When you need to create a special class simply to be used as a return value of a method, it means that you are working around C#'s inability to return multiple values from a method, so the out keyword may be a very good option for you.
On the other hand, if you use the multi-part return value in other places, such as storing them in collections or passing as arguments to other methods, there's probably no need to refactor, because the return object is meaningful.
Compare these two methods:
interface DictionaryReturn<T> {
T Value {get;}
bool Success {get;}
}
...
class Dictionary<K,V> {
...
public DictionaryReturn<V> TryGetValue(K key) {
...
}
}
or
class Dictionary<K,V> {
...
public bool TryGetValue(K key, out V res) {
...
}
}
The first case introduces a special DictionaryReturn<T> class that provides the value and an indicator that the value was found in the dictionary. There is rarely, if ever, a reason to store or use DictionaryReturn<T> objects outside the call to TryGetValue, so the second option is better. Not surprisingly, it is the second option that the designers of the .NET collections library have implemented.
I prefer to use Object with properties. If you use out keyword, you need to define it in other line. It is not as clear as return Object;
The reason to use out keyword is to ensure that code inside the method always sets a value to the out parameter. It's a compile time check that what you intended to do in the function, you did do.

Dynamically determine type to cast to (C#)

My function receives a parameter 'value', of type object. I want to assign it to a member of an object, but the cast doesn't happen implicitly, so I need to specify it explicitly. However, I don't want to actually specify the current type of that member in the object, so I could do this:
positiveOrder.OrderID = (int)value;
But, if business requirements change and OrderIDs are generated and stored in a different way, including a type change to Strings for GUIDS for example, I'll have to come back here and change it, which is undesirable cohesion. I've experimented with various permutations of code like
positiveOrder.OrderID = value as thisOrder.OrderID.GetType();
or
positiveOrder.OrderID = (typeof(thisOrder.OrderID)) value;
But nothing seems to be working. Any ideas on programatically specifying the type to convert to? It can be done at compile time or run time, since the Order class doesn't change.
If positiveOrder.OrderID will always be an integer (even if represented in a string), don't change the member to be anything but an integer. Instead, expose some method that can deal with different source types.
For example:
public void SetOrderID(object value)
{
this.OrderID = Convert.ToInt32(value);
}
See Convert.ToInt32().
Something like:
using System.Reflection;
receiver.GetType().GetProperty(propName).SetValue(receiver, value, null);

Non-read only alternative to anonymous types

In C#, an anonymous type can be as follows:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
// Do stuff
}
}
However, the following will not compile:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
myVar.b = true;
}
}
This is because myVar's fields are read-only and cannot be assigned to. It seems wanting to do something like the latter is fairly common; perhaps the best solution I've seen is to just define a struct outside the method.
However, is there really no other way to make the above block work? The reason it bothers me is, myVar is a local variable of this field, so it seems like it should only be referred to inside the method that uses it. Besides, needing to place the struct outside of the method can make the declaration of an object quite far from its use, especially in a long method.
Put in another way, is there an alternative to anonymous types which will allow me to define a "struct" like this (I realize struct exists in C# and must be defined outside of a method) without making it read-only? If no, is there something fundamentally wrong with wanting to do this, and should I be using a different approach?
No, you'll have to create your own class or struct to do this (preferrably a class if you want it to be mutable - mutable structs are horrible).
If you don't care about Equals/ToString/GetHashCode implementations, that's pretty easy:
public class MyClass {
public bool Foo { get; set; }
public bool Bar { get; set; }
}
(I'd still use properties rather than fields, for various reasons.)
Personally I usually find myself wanting an immutable type which I can pass between methods etc - I want a named version of the existing anonymous type feature...
Is there an alternative to anonymous types which will allow me to concisely define a simple "record" type like this without making it read-only?
No. You'll have to make a nominal type.
If no, is there something fundamentally wrong with wanting to do this?
No, it's a reasonable feature that we have considered before.
I note that in Visual Basic, anonymous types are mutable if you want them to be.
The only thing that is really "fundamentally wrong" about a mutable anonymous type is that it would be dangerous to use one as a hash key. We designed anonymous types with the assumptions that (1) you're going to use them as the keys in equijoins in LINQ query comprehensions, and (2) in LINQ-to-Objects and other implementations, joins will be implemented using hash tables. Therefore anonymous types should be useful as hash keys, and mutable hash keys are dangerous.
In Visual Basic, the GetHashCode implementation does not consume any information from mutable fields of anonymous types. Though that is a reasonable compromise, we simply decided that in C# the extra complexity wasn't worth the effort.
In C# 7 we can leverage named tuples to do the trick:
(bool a, bool b) myVar = (false, true);
if (myVar.a)
{
myVar.b = true;
}
You won't be able to get the nice initialization syntax but the ExpandoObject class introduced in .NET 4 would serve as a viable solution.
dynamic eo = new ExpandoObject();
eo.SomeIntValue = 5;
eo.SomeIntValue = 10; // works fine
For the above types of operation, you should define your own mutable STRUCT. Mutable structs may pose a headache for compiler writers like Eric Lippert, and there are some unfortunate limitations in how .net handles them, but nonetheless the semantics of mutable "Plain Old Data" structs (structs in which all fields are public, and the only public functions which write this are constructors, or are called exclusively from constructors) offer far clearer semantics than can be achieved via classes.
For example, consider the following:
struct Foo {
public int bar;
...other stuff;
}
int test(Action<Foo[]> proc1, Action<Foo> proc2)
{
foo myFoos[] = new Foo[100];
proc1(myFoos);
myFoos[4].bar = 9;
proc2(myFoos[4]); // Pass-by-value
return myFoos[4].bar;
}
Assuming there's no unsafe code and that the passed-in delegates can be called and will return in finite time, what will test() return? The fact that Foo is a struct with a public field bar is sufficient to answer the question: it will return 9, regardless of what else appears in the declaration of Foo, and regardless of what functions are passed in proc1 and proc2. If Foo were a class, one would have to examine every single Action<Foo[]> and Action<Foo> that exists, or will ever exist, to know what test() would return. Determining that Foo is a struct with public field bar seems much easier than examining all past and future functions that might get passed in.
Struct methods which modify this are handled particularly poorly in .net, so if one needs to use a method to modify a struct, it's almost certainly better to use one of these patterns:
myStruct = myStruct.ModifiedInSomeFashion(...); // Approach #1
myStructType.ModifyInSomeFashion(ref myStruct, ...); // Approach #2
than the pattern:
myStruct.ModifyInSomeFashion(...);
Provided one uses the above approach to struct-modifying patterns, however, mutable structs have the advantage of allowing code which is both more efficient and easier to read than immutable structs or immutable classes, and is much less trouble-prone than mutable classes. For things which represent an aggregation of values, with no identity outside the values they contain, mutable class types are often the worst possible representation.
I find it really annoying that you can't set anonymous properties as read/write as you can in VB - often I want to return data from a database using EF/LINQ projection, and then do some massaging of the data in c# that can't be done at the database for whatever reason. The easiest way to do this is to iterate over existing anonymous instances and update properties as you go. NOTE this is not so bad now in EF.Core, as you can mix db functions and .net functions in a single query finally.
My go-to workaround is to use reflection and will be frowned upon and down-voted but works; buyer beware if the underlying implementation changes and all your code breaks.
public static class AnonClassHelper {
public static void SetField<T>(object anonClass, string fieldName, T value) {
var field = anonClass.GetType().GetField($"<{fieldName}>i__Field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
field.SetValue(anonClass, value);
}
}
// usage
AnonClassHelper.SetField(inst, nameof(inst.SomeField), newVal);
An alternative I have used when dealing with strings is to make properties of type StringBuilder, then these individual properties will be settable via the StringBuilder methods after you have an instance of your anonymous type.
I know it is really old question but how about replacing whole anonymous
object:
`
if (myVar.a)
{
myVar = new
{ a = false, b = true };
}
`

Categories