Interesting params of ref feature, any workarounds?
This is not possible. To explain why, first read my essay on why it is that we optimize deallocation of local variables of value type by putting them on the stack:
https://web.archive.org/web/20100224071314/http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx
Now that you understand that, it should be clear why you cannot store a "ref bool" in an array. If you could, then you could have an array which survives longer than the stack variable being referenced. We have two choices: either allow this, and produce programs which crash and die horribly if you get it wrong -- this is the choice made by the designers of C. Or, disallow it, and have a system which is less flexible but more safe. We chose the latter.
But let's think about this a little deeper. If what you want is to pass around "thing which allows me to set a variable", we have that. That's just a delegate:
static void DoStuff<T>(this T thing, params Action<T>[] actions)
{
foreach(var action in actions) action(thing);
}
...
bool b = whatever;
b.DoStuff(x=>{q = x;}, x=>{r = x;} );
Make sense?
Pass infinite params by reference (using keywords params and ref together)
So the simple answer is no, you can´t have a method return an infinite number of references.
What should be the benefit on such a feature? Obvioulsy you want a method that can change any object no matter where it comes from nor who is using it any more. This hardly is a break on the Single-Responsibility-principle of a class, making it a God-object.
What you can do however is create the instances within an enumeration:
private bool Test(object[] differentStructures)
{
differentStructures[0] = someOtherRessource;
differentStructures[1] = anotherDifferentRessource
differentStructures[2] = thirdDifferentRessource
}
And call it like:
var tests = new[] {
default(TestStructOne),
default(TestStructTwo),
default(TestStructOne)
}
Test(tests);
Which will lead to the following:
tests[0] = someOtherRessource;
tests[1] = anotherDifferentRessource
tests[2] = thirdDifferentRessource
Create method with params ref T parameter
On ref
+ params
:
A member can't be a reference. And since params
transforms each parameter into array member this isn't possible.
The only thing I can think of is manually creating a number of overloads.
But in your case I don't see why you need ref
in the first place. To add members to a list you don't need to change the reference itself, and thus don't need to pass it my ref in the first place.
Why can't I pass a various numbers of references to a function?
for some reason one can not use ref and params at the same time. Why so?
Consider these three desirable characteristics of cameras:
lightweight
high-quality lens
inexpensive
You get to have at most two of those in any camera. You never get all three. You can get inexpensive heavy big-lens cameras, or expensive lightweight big-lens cameras, or inexpensive lightweight snapshot cameras, but there are no inexpensive, lightweight cameras with big lenses.
Returning now to your question. Consider these three desirable characteristics of a runtime:
param arrays of ref-to-variable types are legal
type system is safe
local variables that have refs to them are still fast to allocate and deallocate
You get to have any two but you can't have all three. Which two would you like?
You can have ref param arrays and a safe type system at the cost of ref'd local variables being allocated on the garbage collected heap. To my knowledge no one does this, but it is certainly possible.
You can have ref param arrays, all local variables allocated on the temporary pool, and a type system that crashes when you use it wrong. This is the "C/C++" approach; it is possible to take a reference and store it in a location that has longer lifetime than the lifetime of the thing being referenced. If you do that, you can expect to have your C++ program crash and die in the most horrible possible ways by making easy mistakes that are hard to detect. Welcome to the pit of despair.
Or we can make ref param arrays illegal, allocate all local variables on the temporary pool, and have a type system that is verifiably memory-safe. That's the choice we made when building C# and the CLR; welcome to the pit of quality.
Now, what I said above is actually all a big lie. It's a lie because the runtime, and the C# language, actually do support a feature akin to (but not identical to) parameter arrays of refs. It is a pleasant lie and believe me, you want to live in the world where you believe the lie, so I recommend that you take the blue pill and continue to do so.
If you want to take the red pill and find out how deep the rabbit hole goes, you can use the undocumented __arglist
feature of C# to build a C-style variadic method, and then make TypedReference
objects that refer to references of arbitrarily fields or locals of struct types, and then pass arbitrarily many of them to the variadic method. Use either the factory methods of TypedReference
or the undocumented __makeref
feature of C#.
The reason we've kept these features undocumented for the last decade is because they are by design there to be used only for the extremely rare situations where you must write C# code that interoperates cleanly with variadic methods written in other languages.
Correctly using TypedReference
objects is not for the faint of heart and again I strongly recommend against doing so. I have never once done so in production code in many years of writing C#. If you want to pass around references to arbitrarily many variables, pass an array. An array is by definition a collection of variables. That is much safer than passing around a bunch of objects that represent managed addresses of instance or local variables.
How to write method which will accept variable count of parameters by ref
You can use your own class to acquire the indexes. See how:
class IndexReceiver
{
public string Name { get; set; }
public int Index { get; set; }
public static implicit operator IndexReceiver(string name)
{
return new IndexReceiver() { Name = name };
}
}
Then, you define your method like this:
void GetIndexes(params IndexReceiver[] receivers)
{
// Here you read the each IndexReceiver's Name property and write the index.
}
Use the new method like this:
IndexReceiver code = "Code", index = "Index", desc = "desc"
GetIndexes(code, index, desc);
Is there a way to create a Pass-By-Reference list of managed-type variables?
If I understand your question correctly, I don't think what you want to do is possible. Please see this question: Interesting "params of ref" feature, any workarounds?
The only thing I can suggest (which I know doesn't answer your question) is creating a method to avoid duplication of your conditional logic:
void Convert(ref string text)
{
if (string.IsNullOrEmpty(text) || "Blank".Equals(text))
{
text = null;
}
}
Related Topics
How to Add Cookies to Webrequest
How to Get Property Change Notifications with Ef 4.X Dbcontext Generator
Get the Id of Inserted Row Using C#
Dynamically Added Dropdownlists Are Not Firing Selectedindexchanged Event
Generate 16-Bit Grayscale Bitmapdata and Save to File
Queuing in Oneway Wcf Messages Using Windows Service and SQL Server
Test If Object Implements Interface
Most Efficient Method of Self Referencing Tree Using Entity Framework
Garbage Collection When Using Anonymous Delegates for Event Handling
Why Do Members of a Static Class Need to Be Declared as Static? Why Isn't It Just Implicit
How Does One Extract Each Folder Name from a Path
ASP.NET MVC Route to Catch All *.Aspx Requests
Sending an Array of Values to Oracle Procedure to Use in Where in Clause