I'm having a hard time trying to figure out the meaning of this advice from Attribute Usage Guildelines:
Do not define a parameter with both named and positional arguments. The following code example illustrates this pattern.
And the code is:
public class NameAttribute: Attribute
{
string userName;
int age;
// This is a positional argument.
public NameAttribute (string userName)
{
this.userName = userName;
}
public string UserName
{
get
{
return userName;
}
}
// This is a named argument.
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
}
Now, I'm sorry if it's really simple and I am wasting your time. But I just don't understand the meaning and what example demonstrates. The fact that English is not my native language might be a factor, but I didn't experience any difficulties reading MSDN before. I also tried to read the translated version of this article, but it makes even less sense to me.
So, if someone would be kind enough to rephrase and explain it to me, that would be really helpful. If you can also explain why MSDN advises to do so, I'm all ears.
Think about how you would have to use such an attribute:
[Name("Jack", Age = 25)]
public class ClassToDecorate { }
Now, this doesn't look all that clear because two styles are being mixed: UserName is being set via the attribute's constructor ("positional"), but Age is being explicitly set as a property ("named").
The guideline is suggesting that it would be better to redesign the attribute such that exactly one of the following decorations would work:
[Name("Jack", 25)] // Positional only
(or)
[Name(UserName = "Jack", Age = 25)] // Named only
I think you are the victim of a crummy example, it doesn't actually demonstrate the problem. A better example of doing it wrong is adding this constructor:
public NameAttribute (string userName, int age)
{
this.userName = userName;
this.Age = age;
}
Now the client code could use the attribute this way:
[Name("foo", 42)]
and this way:
[Name("foo", Age = 42)]
Both are equally valid, the client programmer won't be able to make up his mind which one to choose. A much nastier example would be this constructor:
public NameAttribute(int age) {
this.userName = "unspecified";
this.Age = age;
}
which allows:
[Name(42, Age = 43)]
Related
I'm a very new programmer and understand we want to minimize code redundancy so when we update we can make as few changes as possible and also minimize errors.
So I have a Student class that I want overloaded constructor so If I do back chaining it's like this.
public class Student
{
string name;
int Id;
public Student()
{
}
public Student(string name)
{
this.name = name;
}
public Student(string name, int Id) :this(name)
{
this.Id = Id;
But this is apparently bad because we want all the code in one constructor for what reason? Ease of reading?
public Student() : this(null, 0)
{ }
public Student(string name) : this(name, 0)
{ }
public Student(string name, int Id)
{
this.name = name;
this.Id = Id;
}
If I do this forward chaining then what happens if we add a new field like string major? If I do forward chaining then I create a new overloaded constructor with the added field. But now I have to change all the other constructors to call the new one. If I do backwards chaining I just create a new constructor and call the previous overloaded one.
public Student(string name, int Id, string major):this(name, Id)
{
this.major=major;
}
This seems like it follows OOP better but all examples in my text book show forward chaining and don't say why I shouldn't use back chaining.
If I used named/optional parameters it's even easier.
public Student(string name = null, int Id = 0, string major = null)
{
this.name = name;
this.Id = Id;
this.major = major;
}
And if I need another field I just have to edit the one and only constructor. This seems to follow OOP principles the best or am I mistaken? It at least eliminates code duplication the most. My assignment was to "implement the student class following the principles of OOP". I know all these are valid but is one way the best/accepted way of coding constructors? Are there shortcomings with named/optional params that I'm missing? As a beginner it's very confusing that there's so many ways to code this.
There is no best way, because they are different, each of them has advantages and disadvantages.
Independent constructors and chained constructors are available since C# 1.0, under most circumstances we use chained constructors but sometimes we have to use the former if the two constructors has totally different things to handle.
class Student
{
public Student()
{
DoSomething();
}
public Student(string name)
{
this.Name = name;
DoAnotherThing();
}
}
Comparing with optional parameters constructor, the above two are much longer, but to be honest, they are much safer. Consider the following case:
public class Student
{
public Student(string firstName = null, string lastName = null)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
//it's working fine
//var danny = new Student("danny", "chen");
//as the business grows a lot of students need a middle name
public Student(string firstName = null, string middleName = null, string lastName = null)
{
this.FirstName = firstName;
this.MiddleName = middleName;
this.LastName = lastName;
}
//for a better sequence the programmer adds middleName between the existing two, bang!
Another difference between them is using reflection. Optional parameters will not generate more constructors for you, and the default values will not be applied if you are invoking the constructor using reflection.
I know all these are valid but is one way the best/accepted way of coding constructors?
Not to the best of my knowledge - you have many options. Your colleagues are the best people to talk to to reach a consensus. C# is becoming a very rich language, and that means that there will be many different ways to achieve the same thing.
Are there shortcomings with named/optional params that I'm missing?
Not to the best of my knowledge. Personally I think this is the best solution, but others may differ.
As a beginner it's very confusing that there's so many ways to code this.
Welcome to programming. There's millions of us programmers, and we're all busy adding complexity to the world!
I suggest looking deeper about this assumption :
"But this is apparently bad because we want all the code in one constructor for what reason"
There is Fluent Interface Pattern that puts these things apart, also I can not strongly argue that this directly translates for constructors.
customer
.NameOfCustomer("Shiv")
.Bornon("12/3/1075")
.StaysAt("Mumbai");
Illustrative implementation :
public class Customer
{
public string FullName { get; set; }
public DateTime DateOfBirth { get; set; }
public string Address { get; set; }
public Customer NameOfCustomer(string name)
{
this.FullName = name;
return this;
}
public Customer BornOn(DateTime dateOfBirth)
{
this.DateOfBirth = dateOfBirth;
return this;
}
public Customer StaysAt(string address)
{
this.Address = address;
return this;
}
}
Example source
This is a partial answer. Your "backwards chaining", with one constructor setting some parameter(s) then calling another constructor for the rest, is very reasonable/sensible for normal functions: one function does part of the work, then calls another function for some other work, and so on.
But for public constructors, any one of them can be called by client code, expecting to get a fully constructed object, fully initialized. Some constructors in your example leave members uninitialized (unless what you want is the default value for the type).
As an alternative, you can have private constructors.
Started with overriding concepts and I override the methods Equals and GetHashCode.
Primarily I came up with this "very simple code":
internal class Person
{
public string name;
public int age;
public string lname;
public Person(string name, int age, string lname)
{
this.name = name;
this.age = age;
this.lname = lname;
}
public override bool Equals(object obj)
{
var person = obj as Person;
if (person != null)
{
return person.age == this.age && person.name == this.name && person.lname == this.lname;
}
return false;
}
public override int GetHashCode()
{
return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();
}
}
While this works great, my "co-developer" Mr.Resharper gave me some suggestions:
Non-readonly fields referenced in GetHashCode(). Suggestions came in this line of code:
return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();
Should we use GetHashCode only for Properties?
To summarise what was discussed in the comments:
Hashing is designed to provide a value that doesn't change for a given object, no matter what happens to it - hence it's best to depend only on readonly fields in your GetHashCode method.
Firstly, I would suggest making the name and lname field readonly, because they probably don't change in your usage scenario.
As for age, this is something that changes regularly, so probably best to store a DateTime for date of birth, which never changes. Then you can make that readonly too.
If you change the value of a field, used in the hash calculation, after the object had been added to a hash based container like Dictionary or HashSet, you are essentially breaking the inner state of the container. Why is that? Because the object had been stored in a bucket corresponding to a hash value based on its initial state. When the state is changed, e.g. 'age' is modified, the object will continue to live in its old bucket in the hash container although this is not the correct bucket based on its current hash code. This can lead to pretty messy behaviour and a lot of headaches. I've written an article on this topic with some very specific examples, so you may want to check it out.
I don't really like the idea of having directly public fields this way.
I would prefer properties, and unless I really needed to change them, I'd limit access to them using the relatively new init feature from c# 9:
// Will only be setable from the constructor. This will effectively make the
// values read-only (and allow them to be used to generate hashes without
// resharper complaining).
public string name {get; init; }
public string lname {get; init; }
// Note: I'd also use an unchanging date for birth:
public DateTime BirthDate {get; init; };
// Add logic below to actually calculate the age here based
// on the diff between current date and birth date above.
public int Age {
get { return ... };
private set;
};
I learned c# recently, so when I learned to write properties, I was taught to do it like this:
public string Name { get; set; }
Auto properties are great! But now I'm trying to do something a little more complicated, so I need to write a custom pair of accessors.
private string _Name;
public string Name {
get { return _Name; }
set { _Name = value }
}
I know the compiler makes a private instance variable down in it's murky depths when one uses autos, but I'm spoiled and don't want that private variable sitting around looking pointless.
Is there a way to use custom accessors without a private variable?
Properties don't need backing variables (fields) at all. While they can be used for encapsulating simple fields you can also use them to access other data.
public Decimal GrandTotal { get { return FreightTotal + TaxTotal + LineTotal; } }
or
public string SomeStatus { get { return SomeMethodCall(); } }
If the goal is to simply encapsulate some field with a property you would need some sort of backing field if you are not using automatic properties.
The answer is No, you cannot do that.
It is because of recursion. (See line numbers 9 and 7):
Line 1 : public string Name
Line 2 : {
Line 3 : get
Line 4 : {
Line 5 : return FirstName + " " + LastName;
Line 6 : }
Line 7 : set
Line 8 : {
Line 9 : Name = value; // <-- Goes back to Line 7
Line 10 : }
Line 11 : }
No, I'm afraid not. The compiler is smart enough to make this happen for you on auto-generated properties, but with standard properties I imagine the logic behind something like that would end up getting in the way and doing more harm than good.
For example, what if I create a property like this...
public int SomeValue
{
get
{
return 0;
}
}
Would the compiler (with the feature you're looking for) create a backing private variable? Why? It doesn't need one.
Additionally, if the private value isn't created until compilation time, what are you going to reference in your code:
public string Name {
get { return _Name; }
set { _Name = value }
}
What is _Name? What if you have another value somewhere else called _Name? Then what would the compiler call the backing value for this property? What if I need two backing values? Would the compiler be smart enough for that?
public string Name
{
get
{
return string.Format("{0} {1}", _FirstName, _LastName);
}
set
{
// some parsing magic
}
}
It's been asked before, but I imagine the answer is going to continue to be "no" for the foreseeable future.
An auto-property is syntactic shorthand for simple direct member access. (And I imagine one of its driving forces was simply to try to get people to stop creating public values directly.) Properties can grow in complexity well beyond that very easily and I personally wouldn't want the compiler trying to figure out what I can easily just tell it to do.
I know this is an old question, but there is at least one other option here. I'm doing something similar to the below for my own app.
This might not exactly be for your use case, but it shows that a custom getter and setter can be used without a private instance variable. In this case, the getter and setter are shortcut or helper methods to access the Name property of the User for the Account.
We can let the value be set by doing Account.AccountUser.Name = "John Doe";, but sometimes that seems a bit clunky and it works against the idea of separation of concerns. Do we want someone using the Account class to know there's a User imbedded in it? If for some reason we don't, we now have a way to still update the User.Name even if we make AccountUser private.
In this case, AccountUser is public, but it doesn't have to be. When it's private, a Json or XML conversion utility (such as Newtonsoft) should ignore the AccountUser and show just the Name as if the Account were a flat model, instead of having multiple levels.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Account
{
public int Id { get; set; }
public User AccountUser { get; set; }
public string Name
{
get
{
return AccountUser.Name;
}
set
{
AccountUser.Name = value;
}
}
}
Validating Primitive Arguments and "Complex Data"
Validating Arguments
When writing a method, arguments should be validated first before any operations are performed. For example, let's say we've got a class representing people:
public class Person
{
public readonly string Name;
public readonly int Age;
public class Person(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
What's wrong with this Person class? name and age aren't validated before their values are set as fields of Person. What do I mean by "validated?" Both argument should be checked that their values are acceptable. For example, what if name's value is an empty string? Or age's value is -10?
Validating the arguments is performed by throwing ArgumentExceptions or derived exceptions when the values are unacceptable. For example:
public class Person(string name, int age)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentNullException
("name", "Cannot be null or empty.");
}
if (age <= 0 || age > 120)
{
throw new ArgumentOutOfRangeException
("age", "Must be greater than 0 and less than 120.");
}
this.Name = name;
this.Age = age;
}
This properly validates the arguments Person's constructor receives.
Tedium ad Nauseum
Because you've been validating arguments for a long time (right?), you're probably tired of writing these if (....) throw Argument... statements in all of your methods.
What can we do to avoid writing String.IsNullOrEmpty a bazillion times throughout your code?
You can look into Code Contracts in .NET 4.0.
You may also want to look at the FluentValidation Library on CodePlex if you don't want to wait for code contracts.
Ultimately, you still need to put the rules that govern argument values somewhere - it just a matter of deciding whether you prefer an imperative style (e.g. string.IsNullOrEmpty) or a declarative one.
Validating your inputs as is a key practice for writing solid code - but it certainly can be repetitive and verbose.
You may be helped by using more complex types rather than primitives.
For example, if you take the time to define something like a PersonName class, you can have the validation there, and you don't have to keep validating it on every other object that needs to have a name on it.
Obviously this is only going to help the problem if you have multiple objects that use the same field types.
You can try using the Castle Validation Framework => http://www.castleproject.org/activerecord/documentation/v1rc1/usersguide/validation.html
OR
You can use a simple validation framework that I created. Both the frameworks uses Attribute based validation. Check out the link below:
http://www.highoncoding.com/Articles/424_Creating_a_Domain_Object_Validation_Framework.aspx
There are options based on Postsharp. code-o-matic is one of them. It lets you write code like this:
public class Person(
[NotNull, NotEmpty] string name,
[NotNull, NotEmpty] int age
)
{
this.Name = name;
this.Age = age;
}
I use this every day at work.
I'll give a solution in the D programming language. I don't know how powerful C# generics and variadics are because I don't use C#, but maybe you could adapt this:
void validate(T...)(T args) { // args is variadic.
foreach(arg; args) { // Iterate over variadic argument list.
static if(isSomeString!(typeof(arg))) { // Introspect to see arg's type.
if(arg.isNullOrEmpty) {
throw new ArgException(
"Problem exists between keyboard and chair.");
}
} else static if(isOtherTypeWithBoilerPlateValidation!(typeof(arg))) {
// Do more boilerplate validation.
}
}
}
Usage:
class Foo {
SomeType myMethod(T arg1, U arg2, V arg3) {
validate(arg1, arg2, arg3);
// Do non-boilerplate validation.
// Method body.
}
}
I am working on a lib that I want to release in open source. I have started writing the tests for the code, and I was wondering how I am suppose to test a property in a .Net object. Lets say I have the following:
public class Person{
#region variables
private string _name = String.Empty;
private string _surname = String.Empty;
#region properties
public string Name{
get{
return _name;
}
}
public string Surname{
get{
return _surname;
}
set{
_surname = value;
}
}
}
I have two questions related to the code:
How do I Unit test a Property that just has a getter (Like Name in the example)
How do I Unit test a Property with a setter and a getter (Like Surname in the example)
I want to test properties that are that simple because I have already found errors in other code were Itellinsense did the wrong autocomplete and the property was not returning the correct variable.
Update: I am not talking about simple properties as the one in the example, they do have some logic behind them and are quite hard to debug. Writing a test that uses the setter to test the getter and vice versa is not good because if there is a fail I won't know which method to blame. I am using properties because they were added as public variables and later more logic had to be added.
Don's waste your time on writing silly
tests for getters and setters.
Another test will probably set the
Name and then get that property so you
will have code coverage for the
getter.
You should test anything public facing, including properties. If you don't test a property, you run the risk that someone may add some logic inside it, breaking the functionality.
Also you shouldn't rely on it being tested in other tests. This makes your tests brittle, and makes it harder to identify where the problem is as a test will be testing more than one thing.
How do I Unit test a Property that
just has a getter (Like Name in the
example)
Really not so different from testing if you had a setter. you'll just need to find another way of determining the output. Could be in a ctor, or the result of other setters/operations on the object.
[Test]
public void NamePropTest()
{
Person p = new Person();
//Some code here that will set up the Person object
// so that you know what the name will be
Assert.AreEqual("some known value...", p.Name);
}
If we had setters for Name and SurName, but only a getter for FullName, the test could look like this:
[Test]
public void NamePropTest()
{
Person p = new Person();
p.Name = "Sean";
p.Surname = "Penn";
Assert.AreEqual("Sean Penn", p.FullName);
}
You should test properties. Also automatic properties!
Unittests are about assuring that changes to the program, don't break the program.
You could end up changing a property implementation at some time, and you want to make sure the program still works as expected. You do that with your tests.
Even if you use automatic properties (as a replacement for fields/member variables), the reason for making them properties is in case you want to change their implementation later on. Then you'll want the tests to be there.
EDIT: (In response to shahkalpesh's comment...)
If you are changing the
implementation, the tests might also
require the change. So, I don't know
of why someone should test simple
get/set?
Starting with this class:
public class TimeOfDay
{
public int Hour{get; private set;}
public int Minute{get; private set;}
public TimeOfDay(int hour, int minute)
{
Hour = hour;
Minute = minute;
}
}
When changing the implementation, the tests are still valid!
public class TimeOfDay
{
public int _minutesSinceMidnight = 0;
public int Hour
{
get { return _minutesSinceMidnight / 60; }
set { _minutesSinceMidnight = value * 60 + Minutes; }
}
public int Minute
{
get { return _minutesSinceMidnight % 60; }
set { _minutesSinceMidnight = Hour * 60 + value; }
}
public TimeOfDay(int hour, int minute)
{
Hour = hour;
Minute = minute;
}
}
Throw in some date and time arithmetic functions or something, and I would like the tests to show that everything still works...
I think you should test, them if you write them like you did. Afterall you can mistype something.
Just something like
var person = New Person();
person.Surname = "test";
Assert.AreEqual("test", person.Surname);
After all TDD and unit testing n general is all about avoiding the most bugs you can.
If by accident you had written this.
public class Person{
#region variables
private string _name = String.Empty;
private string _surname = String.Empty;
#region properties
public string Name{
get{
return _name;
}
}
public string Surname{
get{
return _name;
}
set{
_name = value;
}
}
}
then you would have a bug.
Testing the automatic properties is perhaps less valuable. But that's another question.
Those property should be there because you have usages that needs them. As for these there should be unit tests, you should already have coverage for them.
If there is no scenario that needs them, they possibly shouldn't be there at all.
As I understand, you shouldn't be testing properties (i.e. those which are simple get/set).
I am not sure what version of c# you are using. But, you can use automatic properties to avoid the simple set/get problems that you are facing.
See this link
Don's waste your time on writing silly tests for getters and setters.
Another test will probably set the Name and then get that property so you will have code coverage for the getter.
My question is more related of HOW to
write the test. I have been thinking
about it and I need to access the
private values to make sure that the
properties work as expected, otherwise
I do not know how to do it.
https://stackoverflow.com/users/59332/mandel
Ok...since you insist on knowing how to do it....
[Test]
TestMethod()
{
Person p = new Person();
p.Name = "a name";
p.Surname = "a surname";
Assert.That(p.Name, Is.EqualTo("a name"));
Assert.That(p.Surname, Is.EqualTo("a surname"));
}
However, that only works if you have setters....
If you only have getters there are only two ways I can think of that you can do this.
know the return value in advance and assert against that.
Use Reflection to set the value and then assert against that known value.
A better bit of advice would be to give up and test something worthwhile that actually adds value to your software. Testing getters and setters is an absolute waste of time unless there is something complex going on behind them....which is rarely the case.
I think you meant that your getter-only propoerty uses private fields or other private data. If you need to set them, only way is to get them by Reflection (see all (something)Info classes in System.Reflection). But there is a hard discussion if this is a good practice.