Restrict value of a parameter in a constructor AT DESIGN TIME - c#

I'd like to restrict the value of a number parameter in a constructor to within a certain range.
I know the conventional way is to do something like the following:
public class Foo
{
public int MaxAmount { get; }
public int Amount { get; set; }
public Foo(int amount)
{
if (amount > MaxAmount) { Amount = MaxAmount; }
else if (amount < 1) { Amount = 1; }
else { Amount = amount; }
}
}
But what I don't like about this is that the caller doesn't know when the property gets set to something other than what was specified. I could return an exception instead of silently clamping the value, but that's not very friendly.
What I'd like is something akin to this:
public Foo(int(1, this.MaxAmount) amount) // Where int(minimumValue, maximumValue)
{
Amount = amount;
}
in which one wouldn't even be able to instantiate Foo with an unacceptable value - the framework would prevent it.
Is anything like this possible?
EDIT FOR CLARITY:
What I'm after is a means by which the parameter itself can carry and communicate the information about its constraints - in a 'baked in' fashion which might, for example, surface in Intellisense when you wrote the call. So, I'd avoid the work of even attempting to instantiate the class if the values for the parameters were not valid.
If, for example, the program is running and the user types a number (N) and presses a button which creates a new Foo with an illegal quantity of N, I now have an exception to handle and something to debug and fix. Why even allow it in the first place? If Foo has been explicitly defined as having an upper boundary of 4 for its Amount property, what's the point of allowing the developer to write Foo(5) when I could have informed him that the value he's passing is not valid at the time that he wrote it?
If there's some syntactic sugar, like ParameterConstraint or something, that is handled by the Framework for me so that I don't have to roll my own into every class I write, I think that would be very useful.

I could return an exception instead of silently clamping the value, but that's not very friendly.
Say what? What do you mean, "friendly"? The caller isn't your friend, it's another piece of code that is trying to set an out of range value. The developer who wrote the code should be told immediately that he's doing something wrong.
Throw an exception!

You can do this using static-contract checking with Code Contracts (Premium only - The standard edition only offers runtime contract checking).
The syntax is simply
public Foo(int amount) {
Contract.Requires(amount < MaxAmount);
...
}
(Requires) contracts are evaluated by checking that the arguments is constrained when calling the method. In your instance, it will be difficult to evaluate the constructor argument with against the instance field MaxAmount, because you cannot check that value beforehand. (Make MaxValue static to solve this).
Example of such call.
int val = _getFromSomewhere();
var foo = new Foo(val);
//This May produce compile time error
// because the contract checker cannot prove you contract is met.
The fix would be to make sure you put the constraint where you call is made.
int val = _getFromSomewhere();
if (val < Foo.MaxAmount)
var foo = new Foo(val);
//Will always compile fine, because contract is met.
When you install Contracts, the static checker isn't turned on by default. Your project properties will have an extra tab where you can configure the contract options and enable static checking.

You will need to wrap the parameter up in a new type then. ints know what their max amount is, and it is int.MaxValue. If it is truly the case that the parameter itself knows its own max amount, and that it isn't something specific to class Foo, then you will need to create another type that checks the amount passed in to it. As it stands, the signature of Foo's constructor accepts any int data structure.

Either throw the exception or provide a static property to validate the amount
public static bool ValidateAmount(int amount)
{
if(amount > MaxAmount)
return false;
return true;
}

Not for sure if this works for properties types in C#, but you might be able to define an enumeration contain all of the acceptable values and then set the data type of the property to that enumeration. That would force the caller to use the enumeration and thus know what values are acceptable. Of course, if you have a lot of values in the acceptable range, the enumeration would be unwieldy.

Related

dynamically return an object based on string description of it's type

I have a database which stores user inputs in an abstract stringified form. These user inputs have a varchar column which describes its type (string, decimal, bool, dropdown etc).
Now this get's send to the front end to display some input elements in the browser. This works great!
However since the input is so generic the value is also a varchar. The problem I am facing is that I need to do some validation on the value. (e.g. some string input have a maxLength or regex specified, a decimal can have a min and max value).
so once I get back the value the user entered it is in string format and I want to parse it to the correct native type so I can start validating it.
I would like a function which returns the parsed value in it's correct type.
so I would have a function which is something like this:
public {something here} ParseValue(InputObject object, string type) {
// parse here based on type
// InputObject has a few properties like value, min, max, regex etc
// all as a string.
// for instance if type is datetime I want to return a new object
// which has parsed the value, min and max as datetime.
// it should also be possible for the type to be decimal and min, max
// and value should be decimal in the outputObject
}
I am coming from a dynamically typed background so I have no idea how to do something like this. or even if it is possible.
any help is appreciated!
You'd be best off if you don't directly try to evaluate the type by the Database-Datatype and instead store the "real" type in a seperate DB-Column. Except if you build an association between C#-Types and Database-Types because you can do something like this then:
String val = "123";
String type = "System.Int32";
Type tempType = Type.GetType(type);
if (tempType == null)
return null;
dynamic result = Convert.ChangeType(val, tempType);
Of course this would be applicable to the boundary values also. Note that Convert.ChangeType only works for very popular Types and is not universally useable and that it throws an Exception if theres something failing which need to be catched also.
What you could do is create an interface IValidatable that defines a method like Validate(). Then you could use that as a return type. Then you just parse your value using a switch (probably delegate this to some method or class) to an implementation of IValidatable. E.g.
public interface IValidatable {
bool Validate();
}
public class ValidateableInteger : IValidatable {
private int _value;
public ValidateableInteger(int i) {
_value = i;
}
bool Validate() {
//code where you validate your integer.
}
}
Note that this is not very flexible as you only have 1 method called validate, though clearly you can define multiple more generic methods that could implement different validations.
Moreover you can create more specific interfaces for e.g. numeric types (e.g. IValidateableNumeric and ValidateableInt : IValidateableNumeric)
Note that you're basically typing your input here though, which is kindof weird and unnecessary given the fact that you can just work with typed data to begin with.
In the end I would discourage people from bypassing type system this way. In this case especially there are plenty better ways of creating form elements while using typed data (checkout the Razor template engine).

C# - using a generic enum (or alternative method for controlling lists)

I'm writing a pathfinding algorithm for a game, but trying to keep it generic so it can be used in future applications.
I have a Node class which holds X, Y and "PassableType".
The NodeGrid class stores an array of Nodes, containing the graph information of how they connect, and then has a FindAStarPath() function, which takes as its parameters StartNode, EndNode, and params for "PassableTypes".
My problem is determining what type "PassableType" should have.
Ideally what I want is to be able to use a generic enum - i.e. a restricted list which each game defines. The Node will hold a single element of that list, to say what path type it is (the current game may use Path, Grass, Wall, etc)
Thus, when an entity tries to path, it provides the pathfinding function which types to treat as "passable". So a man may use
FindAStarPath(CurrentNode, DestinationNode, "Path", "Floor", "Door");
but a car may just use
FindAStarPath(StartNode, EndNode, "Road");
My problem is I can't work out how to get the NodeGrid to take a Generic enum or equivalent logic.
At the moment I have it taking strings, but this means I have to write
MyEnum.Road.ToString()
every time I use it.
Ideally I'd like to do something like
NodeGrid<MyEnum> CurrentNodeGrid = new NodeGrid<MyEnum>()
And then Nodes will take a MyEnum for their passableType, as will the pathfinding functions, thus allowing each game to have a different set of tile types for pathing.
But I can't define NodeGrid as:
public class NodeGrid<T> where T:enum
For clarity, the only part of the pathfinding function which uses this enum is this (contained within Node):
public bool IsPassable(string[] passableTypes)
{
for (var i = 0; i < passableTypes.Count(); i++)
{
if (this.PassableType == passableTypes[i]) return true;
}
return false;
}
Thanks
Haighstrom
Unless you're using some specific functionality of enums (like Enum.Parse), then I don't see any reason to constrain it to them. By freeing constraints, callers can use whatever types they see fit, beit enum, or a set of string values (as you currently have it), or a set of custom class instances to check against.
public class NodeGrid<T>
{
public T PassableType { get; private set; }
public bool IsPassable(params T[] passableTypes)
{
return IsPassable((IEnumerable<T>)passableTypes);
}
public bool IsPassable(IEnumerable<T> passableTypes)
{
foreach(T passType in passableTypes)
{
if (EqualityComparer<T>.Default.Equals(this.PassableType, passType))
return true;
}
return false;
}
}
But since we're now using generics, you can't use the == comparison anymore. The simplest is to leverage the EqualityComparer.Default utility. The main reason to use this over directly calling this.PassableType.Equals(passType) is it will perform null checks and leverage generics properly where applicable and if the types implement IEquatable<T>, then use those generic versions. Probably some other minor things. It will usually eventually call the Object.Equals overload.
Some examples based on your question:
//using a custom enum, calls the params T[] overload
NodeGrid<MyCarEnum> carNode = ...
carNode.IsPassable(MyCarEnum.Road, MyCarEnum.Tunnel);
//demonstrates receiving a set of pass types strings from an external source
List<string> passTypes = new List<string>("Path", "Floor", "Door");
NodeGrid<string> personNode = ...
personNode.IsPassable(passTypes) //calls the IEnumerable<T> overload
//feel free to declare enums wherever you want,
//it can avoid potential mixups like this:
NodeGrid<string> airplaneNode = ...
NodeGrid<string> personNode = ...
NodeGrid<MyCarEnum> carNode = ...
airplaneNode.IsPassable("Floor"); //makes no sense, but will compile
personNode.IsPassable("Clouds"); //makes no sense, but will compile
carNode.IsPassable("Sky"); //compile error: was expected a MyCarEnum value

Objects with many value checks c#

I want to see your ideas on a efficient way to check values of a newly serialized object.
Example I have an xml document I have serialized into an object, now I want to do value checks. First and most basic idea I can think of is to use nested if statments and checks each property, could be from one value checking that it has he correct url format, to checking another proprieties value that is a date but making sue it is in the correct range etc.
So my question is how would people do checks on all values in an object? Type checks are not important as this is already taken care of it is more to do with the value itself. It needs to be for quite large objects this is why I did not really want to use nested if statements.
Edit:
I want to achieve complete value validation on all properties in a given object.
I want to check the value it self not that it is null. I want to check the value for specific things if i have, an object with many properties one is of type string and named homepage.
I want to be able to check that the string in the in the correct URL format if not fail. This is just one example in the same object I could check that a date is in a given range if any are not I will return false or some form of fail.
I am using c# .net 4.
Try to use Fluent Validation, it is separation of concerns and configure validation out of your object
public class Validator<T>
{
List<Func<T,bool>> _verifiers = new List<Func<T, bool>>();
public void AddPropertyValidator(Func<T, bool> propValidator)
{
_verifiers.Add(propValidator);
}
public bool IsValid(T objectToValidate)
{
try {
return _verifiers.All(pv => pv(objectToValidate));
} catch(Exception) {
return false;
}
}
}
class ExampleObject {
public string Name {get; set;}
public int BirthYear { get;set;}
}
public static void Main(string[] args)
{
var validator = new Validator<ExampleObject>();
validator.AddPropertyValidator(o => !string.IsNullOrEmpty(o.Name));
validator.AddPropertyValidator(o => o.BirthYear > 1900 && o.BirthYear < DateTime.Now.Year );
validator.AddPropertyValidator(o => o.Name.Length > 3);
validator.Validate(new ExampleObject());
}
I suggest using Automapper with a ValueResolver. You can deserialize the XML into an object in a very elegant way using autommaper and check if the values you get are valid with a ValueResolver.
You can use a base ValueResolver that check for Nulls or invalid casts, and some CustomResolver's that check if the Values you get are correct.
It might not be exacly what you are looking for, but I think it's an elegant way to do it.
Check this out here: http://dannydouglass.com/2010/11/06/simplify-using-xml-data-with-automapper-and-linqtoxml
In functional languages, such as Haskell, your problem could be solved with the Maybe-monad:
The Maybe monad embodies the strategy of combining a chain of
computations that may each return Nothing by ending the chain early if
any step produces Nothing as output. It is useful when a computation
entails a sequence of steps that depend on one another, and in which
some steps may fail to return a value.
Replace Nothing with null, and the same thing applies for C#.
There are several ways to try and solve the problem, none of them are particularly pretty. If you want a runtime-validation that something is not null, you could use an AOP framework to inject null-checking code into your type. Otherwise you would really have to end up doing nested if checks for null, which is not only ugly, it will probably violate the Law of Demeter.
As a compromise, you could use a Maybe-monad like set of extension methods, which would allow you to query the object, and choose what to do in case one of the properties is null.
Have a look at this article by Dmitri Nesteruk: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
Hope that helps.
I assume your question is: How do I efficiently check whether my object is valid?
If so, it does not matter that your object was just deserialized from some text source. If your question regards checking the object while deserializing to quickly stop deserializing if an error is found, that is another issue and you should update your question.
Validating an object efficiently is not often discussed when it comes to C# and administrative tools. The reason is that it is very quick no matter how you do it. It is more common to discuss how to do the checks in a manner that is easy to read and easily maintained.
Since your question is about efficiency, here are some ideas:
If you have a huge number of objects to be checked and performance is of key importance, you might want to change your objects into arrays of data so that they can be checked in a consistent manner. Example:
Instead of having MyObject[] MyObjects where MyObject has a lot of properties, break out each property and put them into an array like this:
int[] MyFirstProperties
float[] MySecondProperties
This way, the loop that traverses the list and checks the values, can be as quick as possible and you will not have many cache misses in the CPU cache, since you loop forward in the memory. Just be sure to use regular arrays or lists that are not implemented as linked lists, since that is likely to generate a lot of cache misses.
If you do not want to break up your objects into arrays of properties, it seems that top speed is not of interest but almost top speed. Then, your best bet is to keep your objects in a serial array and do:
.
bool wasOk = true;
foreach (MyObject obj in MyObjects)
{
if (obj.MyFirstProperty == someBadValue)
{
wasOk = false;
break;
}
if (obj.MySecondProperty == someOtherBadValue)
{
wasOk = false;
break;
}
}
This checks whether all your objects' properties are ok. I am not sure what your case really is but I think you get the point. Speed is already great when it comes to just checking properties of an object.
If you do string compares, make sure that you use x = y where possible, instead of using more sophisticated string compares, since x = y has a few quick opt outs, like if any of them is null, return, if the memory address is the same, the strings are equal and a few more clever things if I remember correctly. For any Java guy reading this, do not do this in Java!!! It will work sometimes but not always.
If I did not answer your question, you need to improve your question.
I'm not certain I understand the depth of your question but, wouldn't you just do somthing like this,
public SomeClass
{
private const string UrlValidatorRegex = "http://...
private const DateTime MinValidSomeDate = ...
private const DateTime MaxValidSomeDate = ...
public string SomeUrl { get; set; }
public DateTime SomeDate { get; set; }
...
private ValidationResult ValidateProperties()
{
var urlValidator = new RegEx(urlValidatorRegex);
if (!urlValidator.IsMatch(this.Someurl))
{
return new ValidationResult
{
IsValid = false,
Message = "SomeUrl format invalid."
};
}
if (this.SomeDate < MinValidSomeDate
|| this.SomeDate > MinValidSomeDate)
{
return new ValidationResult
{
IsValid = false,
Message = "SomeDate outside permitted bounds."
};
}
...
// Check other fields and properties here, return false on failure.
...
return new ValidationResult
{
IsValid = true,
};
}
...
private struct ValidationResult
{
public bool IsValid;
public string Message;
}
}
The exact valdiation code would vary depending on how you would like your class to work, no? Consider a property of a familar type,
public string SomeString { get; set; }
What are the valid values for this property. Both null and string.Empty may or may not be valid depending on the Class adorned with the property. There may be maximal length that should be allowed but, these details would vary by implementation.
If any suggested answer is more complicated than code above without offering an increase in performance or functionality, can it be more efficient?
Is your question actually, how can I check the values on an object without having to write much code?

Value object with "specified" flag

I need to pass values to a method, along with an indication of whether each value is specified or unspecified, since null is a valid value itself, and therefore cannot be interpreted as "unspecified".
I took the generic approach and created a simple container for such values (see below), but is this the right way to go? Are there better ways to approach this problem - e.g. does a class like this already exist in the framework?
public struct Omissible<T>
{
public readonly T Value;
public readonly bool IsSpecified;
public static readonly Omissible<T> Unspecified;
public Omissible(T value)
{
this.Value = value;
this.IsSpecified = true;
}
}
The method signature could look like the following, allowing the caller to indicate that certain values shouldn't be updated (unspecified), others should be set to null/another value (specified).
public void BulkUpdate(int[] itemIds,
Omissible<int?> value1, Omissible<string> value2) // etc.
This is the best one can theoretically do. In order to distinguish a general T from a "T or null" you need one possible state more than a variable of type T can hold.
For example, a 32 bit int can hold 2^32 states. If you want to save a null value in addition you need 2^32 + 1 possible states which does not fit into a 4 byte location.
So you need a bool value in addition. (Theoretically speaking you just need log2(2^32 + 1) - 32 bits for the Omissible<int> case, but an easy way to store this is a bool).

Can parameters be constant?

I'm looking for the C# equivalent of Java's final. Does it exist?
Does C# have anything like the following:
public Foo(final int bar);
In the above example, bar is a read only variable and cannot be changed by Foo(). Is there any way to do this in C#?
For instance, maybe I have a long method that will be working with x, y, and z coordinates of some object (ints). I want to be absolutely certain that the function doesn't alter these values in any way, thereby corrupting the data. Thus, I would like to declare them readonly.
public Foo(int x, int y, int z) {
// do stuff
x++; // oops. This corrupts the data. Can this be caught at compile time?
// do more stuff, assuming x is still the original value.
}
Unfortunately you cannot do this in C#.
The const keyword can only be used for local variables and fields.
The readonly keyword can only be used on fields.
NOTE: The Java language also supports having final parameters to a method. This functionality is non-existent in C#.
from http://www.25hoursaday.com/CsharpVsJava.html
EDIT (2019/08/13):
I'm throwing this in for visibility since this is accepted and highest on the list. It's now kind of possible with in parameters. See the answer below this one for details.
This is now possible in C# version 7.2:
You can use the in keyword in the method signature. MSDN documentation.
The in keyword should be added before specifying a method's argument.
Example, a valid method in C# 7.2:
public long Add(in long x, in long y)
{
return x + y;
}
While the following is not allowed:
public long Add(in long x, in long y)
{
x = 10; // It is not allowed to modify an in-argument.
return x + y;
}
Following error will be shown when trying to modify either x or y since they are marked with in:
Cannot assign to variable 'in long' because it is a readonly variable
Marking an argument with in means:
This method does not modify the value of the argument used as this parameter.
The answer: C# doesn't have the const functionality like C++.
I agree with Bennett Dill.
The const keyword is very useful. In the example, you used an int and people don't get your point. But, why if you parameter is an user huge and complex object that can't be changed inside that function? That's the use of const keyword: parameter can't change inside that method because [whatever reason here] that doesn't matters for that method. Const keyword is very powerful and I really miss it in C#.
Here's a short and sweet answer that will probably get a lot of down votes. I haven't read all of the posts and comments, so please forgive me if this has been previously suggested.
Why not take your parameters and pass them into an object that exposes them as immutable and then use that object in your method?
I realize this is probably a very obvious work around that has already been considered and the OP is trying to avoid doing this by asking this question, but I felt it should be here none-the-less...
Good luck :-)
I'll start with the int portion. int is a value type, and in .Net that means you really are dealing with a copy. It's a really weird design constraint to tell a method "You can have a copy of this value. It's your copy, not mine; I'll never see it again. But you can't change the copy." It's implicit in the method call that copying this value is okay, otherwise we couldn't have safely called the method. If the method needs the original, leave it to the implementer to make a copy to save it. Either give the method the value or do not give the method the value. Don't go all wishy-washy in between.
Let's move on to reference types. Now it gets a little confusing. Do you mean a constant reference, where the reference itself cannot be changed, or a completely locked, unchangeable object? If the former, references in .Net by default are passed by value. That is, you get a copy of the reference. So we have essentially the same situation as for value types. If the implementor will need the original reference they can keep it themselves.
That just leaves us with constant (locked/immutable) object. This might seem okay from a runtime perspective, but how is the compiler to enforce it? Since properties and methods can all have side effects, you'd essentially be limited to read-only field access. Such an object isn't likely to be very interesting.
Create an interface for your class that has only readonly property accessors. Then have your parameter be of that interface rather than the class itself. Example:
public interface IExample
{
int ReadonlyValue { get; }
}
public class Example : IExample
{
public int Value { get; set; }
public int ReadonlyValue { get { return this.Value; } }
}
public void Foo(IExample example)
{
// Now only has access to the get accessors for the properties
}
For structs, create a generic const wrapper.
public struct Const<T>
{
public T Value { get; private set; }
public Const(T value)
{
this.Value = value;
}
}
public Foo(Const<float> X, Const<float> Y, Const<float> Z)
{
// Can only read these values
}
Its worth noting though, that its strange that you want to do what you're asking to do regarding structs, as the writer of the method you should expect to know whats going on in that method. It won't affect the values passed in to modify them within the method, so your only concern is making sure you behave yourself in the method you're writing. There comes a point where vigilance and clean code are the key, over enforcing const and other such rules.
I know this might be little late.
But for people that are still searching other ways for this, there might be another way around this limitation of C# standard.
We could write wrapper class ReadOnly<T> where T : struct.
With implicit conversion to base type T.
But only explicit conversion to wrapper<T> class.
Which will enforce compiler errors if developer tries implicit set to value of ReadOnly<T> type.
As I will demonstrate two possible uses below.
USAGE 1 required caller definition to change. This usage will have only use in testing for correctness of your "TestCalled" functions code. While on release level/builds you shouldn't use it. Since in large scale mathematical operations might overkill in conversions, and make your code slow. I wouldn't use it, but for demonstration purpose only I have posted it.
USAGE 2 which I would suggest, has Debug vs Release use demonstrated in TestCalled2 function. Also there would be no conversion in TestCaller function when using this approach, but it requires a little more of coding of TestCaller2 definitions using compiler conditioning. You can notice compiler errors in debug configuration, while on release configuration all code in TestCalled2 function will compile successfully.
using System;
using System.Collections.Generic;
public class ReadOnly<VT>
where VT : struct
{
private VT value;
public ReadOnly(VT value)
{
this.value = value;
}
public static implicit operator VT(ReadOnly<VT> rvalue)
{
return rvalue.value;
}
public static explicit operator ReadOnly<VT>(VT rvalue)
{
return new ReadOnly<VT>(rvalue);
}
}
public static class TestFunctionArguments
{
static void TestCall()
{
long a = 0;
// CALL USAGE 1.
// explicite cast must exist in call to this function
// and clearly states it will be readonly inside TestCalled function.
TestCalled(a); // invalid call, we must explicit cast to ReadOnly<T>
TestCalled((ReadOnly<long>)a); // explicit cast to ReadOnly<T>
// CALL USAGE 2.
// Debug vs Release call has no difference - no compiler errors
TestCalled2(a);
}
// ARG USAGE 1.
static void TestCalled(ReadOnly<long> a)
{
// invalid operations, compiler errors
a = 10L;
a += 2L;
a -= 2L;
a *= 2L;
a /= 2L;
a++;
a--;
// valid operations
long l;
l = a + 2;
l = a - 2;
l = a * 2;
l = a / 2;
l = a ^ 2;
l = a | 2;
l = a & 2;
l = a << 2;
l = a >> 2;
l = ~a;
}
// ARG USAGE 2.
#if DEBUG
static void TestCalled2(long a2_writable)
{
ReadOnly<long> a = new ReadOnly<long>(a2_writable);
#else
static void TestCalled2(long a)
{
#endif
// invalid operations
// compiler will have errors in debug configuration
// compiler will compile in release
a = 10L;
a += 2L;
a -= 2L;
a *= 2L;
a /= 2L;
a++;
a--;
// valid operations
// compiler will compile in both, debug and release configurations
long l;
l = a + 2;
l = a - 2;
l = a * 2;
l = a / 2;
l = a ^ 2;
l = a | 2;
l = a & 2;
l = a << 2;
l = a >> 2;
l = ~a;
}
}
If you often run into trouble like this then you should consider "apps hungarian". The good kind, as opposed to the bad kind. While this doesn't normally tries to express constant-ness of a method parameter (that's just too unusual), there is certainly nothing that stops you from tacking an extra "c" before the identifier name.
To all those aching to slam the downvote button now, please read the opinions of these luminaries on the topic:
Eric Lippert
Larry Osterman
Joel Spolsky
If struct is passed into a method, unless it's passed by ref, it will not be changed by the method it's passed into. So in that sense, yes.
Can you create a parameter whose value can't be assigned within the method or whose properties cannot be set while within the method? No. You cannot prevent the value from being assigned within the method, but you can prevent it's properties from being set by creating an immutable type.
The question isn't whether the parameter or it's properties can be assigned to within the method. The question is what it will be when the method exits.
The only time any outside data is going to be altered is if you pass a class in and change one of it's properties, or if you pass a value by using the ref keyword. The situation you've outlined does neither.
The recommended (well, by me) is to use an interface that provides read only access to the members. Remembering that if the "real" member is a reference type, then only provide access to an interface supporting read operations for that type -- recursing down the entire object hierarchy.

Categories