The following code generates StackOverFlowException. The question is why? It looks legit to me...
using System;
namespace learning
{
public class TestClass
{
private String name;
public String Name
{
get => Name;
set => name = value;
}
}
class Program
{
static void Main(string[] args)
{
TestClass e = new TestClass();
Console.WriteLine(e.Name);
}
}
}
I tried removing the namespace learning {...} but it didn't change anything.
Your property is returning itself:
public String Name
{
get => Name;
set => name = value;
}
Instead, it should return the field name (case sensitive):
public String Name
{
get => name;
set => name = value;
}
You are making a recursive call to the property Name, target the field instead i.e name
public String Name
{
get => name;
This is a perfect reason why i like to underscore my fields names _name, The other being so i don't have to use this.name in methods or constructor
Related
I'm trying to simplify code for extracting data from property attribute.
Attribute:
[AttributeUsage(AttributeTargets.Property)]
class NameAttribute : Attribute
{
public string Name { get; }
public ColumnAttribute(string name)
{
Name = name;
}
}
Attribute contents extraction code ( null-checks removed ):
public static string GetName<T>(string propName)
{
var propertyInfo = typeof(T).GetProperty(propName);
var nameAttribute = (NameAttribute)propertyInfo.GetCustomAttributes(typeof(NameAttribute)).FirstOrDefault();
return nameAttribute.Name;
}
Sample class:
class TestClass
{
[Column("SomeName")]
public object NamedProperty { get; set; }
}
Call sample:
var name = GetName<TestClass>(nameof(TestClass.NamedProperty))
Is it any way to rewrite attribute contents extraction method to simplify/shorten its call. It's too inconvenient for me due to its length.
Something like CallerMemberNameAttribute would be great but i found nothing.
Your syntax is already pretty short. The only redundant information is the class name, everything else is needed, it won't get much shorter. You could have a shorter syntax n your call as demonstrated below, where you remove the redundancy of the class name. However, that comes at the cost or a more complex implementation. It's up to you to decide if that's worth it:
namespace ConsoleApp2
{
using System;
using System.Linq.Expressions;
using System.Reflection;
static class Program
{
// your old method:
public static string GetName<T>(string propName)
{
var propertyInfo = typeof(T).GetProperty(propName);
var nameAttribute = propertyInfo.GetCustomAttribute(typeof(NameAttribute)) as NameAttribute;
return nameAttribute.Name;
}
// new syntax method. Still calls your old method under the hood.
public static string GetName<TClass, TProperty>(Expression<Func<TClass, TProperty>> action)
{
MemberExpression expression = action.Body as MemberExpression;
return GetName<TClass>(expression.Member.Name);
}
static void Main()
{
// you had to type "TestClass" twice
var name = GetName<TestClass>(nameof(TestClass.NamedProperty));
// slightly less intuitive, but no redundant information anymore
var name2 = GetName((TestClass x) => x.NamedProperty);
Console.WriteLine(name);
Console.WriteLine(name2);
Console.ReadLine();
}
}
[AttributeUsage(AttributeTargets.Property)]
class NameAttribute : Attribute
{
public string Name { get; }
public NameAttribute(string name)
{
this.Name = name;
}
}
class TestClass
{
[Name("SomeName")]
public object NamedProperty { get; set; }
}
}
The output is the same:
SomeName
SomeName
Just got to know about C# snippet. But i am unable to use them in my code.
Help me out please, I am messed up with get set and how they work.
Here is my test class named "myclass"
namespace WindowsFormsApplication1
{
class myclass
{
public string getmessage(string givenName)
{
return "HB "+givenName;
}
private string bmessage;
public string MyProperty
{
get { return bmessage; }
set { bmessage = value; }
}
}
}
In button code from my form. I am unable to use these get set.
It ll be great if someone clears that how can i use these get set.
Moreover what is "MyProperty" here? I know it is not a method. What is its purpose? Thanks
Snippets itself are not executable statements. But are short-cuts that help you in writing executable statements.
For e.g.
If we write prop and press enter, it will give you a auto-generated property. You just have to change Datatype and Property Name.
Similarly propfull will give a property with get and set parts.
In your case MyProperty is the Property Name and string is the DataType. bmessage is the backing field for your property.
The properties of a class are set and retrieved by using set/get methods. Basically these are also methods.
namespace BusinessObjects
{
public class class_BusinessObjects
{
int StusentId;
string StudentName;
public class_BusinessObjects ()
{
StusentId = 0;
StudentName = string.Empty;
}
public int StusentId
{
get
{
return Id;
}
set
{
Id = value;
}
}
public string StudentName
{
get
{
return Name;
}
set
{
Name = value;
}
}
}
}
using BusinessObjects;
namespace MyModel
{
public class A
{
public class_BusinessObjects Dispaly(int id, string name)
{
class_BusinessObjects obj = new class_BusinessObjects();
obj.StusentId = id;
obj.StudentName = name;
return obj;
}
}
}
In the piece of code below, the output is;
Ernie
Bert
Elmo
Why is the last output is Elmo? Shouldn't it be Ernie? Because i instantiate dog.Creature object with new Cat();. i thought that the Name property of Cat class overrides the Name property of Creature class.
class Class1
{
public static void Main(string[] args)
{
var dog = new Dog();
var cat = new Cat();
dog.Creature = new Cat();
Console.WriteLine(cat.Name); //outputs Ernie
Console.WriteLine(dog.Name); //outputs Bert
Console.WriteLine(dog.Creature.Name); //outputs Elmo, why not Ernie?
Console.Read();
}
}
public class Animal<T> where T : Creature
{
public T Creature { get; set; }
private string _name = "Oscar";
public string Name { get { return _name; } set { _name = value; } }
}
public class Creature
{
private string _name = "Elmo";
public string Name { get { return _name; } set { _name = value; } }
}
public class Cat : Creature
{
private string _name = "Ernie";
public string Name { get { return _name; } set { _name = value; } }
}
public class Dog : Animal<Creature>
{
private string _name = "Bert";
public string Name { get { return _name; } set { _name = value; } }
}
Firstly, this has nothing to do with generics. You'll get exactly the same behaviour if you write:
Creature cat = new Cat();
Console.WriteLine(cat.Name);
Don't forget that the compile-time type of Dog.Creature is Creature.
i thought that the Name property of Cat class overrides the Name property of Creature class.
No, because it's not a virtual property and you haven't used override. You should have a compile-time warning explicitly saying that you're hiding the member, not overriding it:
Test.cs(30,19): warning CS0108: 'Cat.Name' hides inherited member
'Creature.Name'. Use the new keyword if hiding was intended.
If you change Cat and Creature to be like this, it will work:
public class Creature
{
private string _name = "Elmo";
public virtual string Name { get { return _name; } set { _name = value; } }
}
public class Cat : Creature
{
private string _name = "Ernie";
public override string Name { get { return _name; } set { _name = value; } }
}
... but personally I'd try to avoid this anyway. Why not just use the setter in Creature? Why would you want there to be two _name fields in a Cat object? It's not like they're meant to serve different purposes, is it?
It's not clear what you're trying to achieve, but I'd almost certainly give the Creature class a constructor taking the name as a parameter. I'd probably make the property read-only if at all possible, too.
A good practice is to read the warnings the IDE gives you.
warning CS0108: 'Program.Cat.Name' hides inherited member 'Program.Creature.Name'. Use the new keyword if hiding was intended.
warning CS0108: 'Program.Dog.Name' hides inherited member 'Program.Animal<Program.Creature>.Name'. Use the new keyword if hiding was intended.
I thought that the Name property of Cat class overrides the Name property of Creature class
No, it hides it. You have two different properties with the same name. If you want to override it, you need to make the base property virtual and use the override keyword on the inherited class:
public class Creature
{
private string _name = "Elmo";
public virtual string Name { get { return _name; } set { _name = value; } }
}
public class Cat : Creature
{
private string _name = "Ernie";
public override string Name { get { return _name; } set { _name = value; } }
}
As to why you are seeing "Elmo" instead of "Ernie" - it's because Dog is an Animal<Creature>, so the property Dog.Creature is of type Creature. Even though you pass in a Cat, since the Name property is not overridden, Creature.Name is called. If you had overrode Name, then Cat.Name would be called instead.
We use backing fields for a lot of properties on our domain objects, for example:
protected string _firstname;
public virtual string Firstname
{
get { return _firstname; }
set { _firstname = value; }
}
I've occasionally made stupid typos like the example below, and would like to write a single test that verifies all these properties, rather than manually doing a test per object.
public virtual string Firstname
{
get { return _firstname; }
set { _firstname = Firstname; }
}
Would it be easy to write or does a library already exist to test these backing fields get/set correctly? This would only run on properties with setters and (presumably) a backing field that matches the property name using camel-case underscore
Another solution would be to use automatic properties to eliminate this problem:
public virtual string FirstName { get; set; }
UPDATE (see comments, backing field seems needed):
Another possibility is to generate the pocos. Simple t4-template 'Person.tt'
<## template language="C#" #>
<# var pocos = new [] {
Tuple.Create("FirstName", "string"),
Tuple.Create("LastName", "string"),
Tuple.Create("Age", "int")}; #>
public partial class Person {
<# foreach(var t in pocos) {#>
protected <#= t.Item2#> _<#= t.Item1.ToLowerInvariant()#>;
public virtual <#= t.Item2#> <#= t.Item1#>
{
get { return _<#= t.Item1.ToLowerInvariant()#>; }
set { _<#= t.Item1.ToLowerInvariant()#> = value; }
}
<#}#>
}
Now this could of course bring with it as many problems as it solves but it may be worth looking at ... maybe:)
Apart from using auto properties I would think of using reflection to test out my models.. .
Just write a generic method that gets all the properties of your class and then use methods like these:
/ get value of property: public double Number
double value = (double)numberPropertyInfo.GetValue(calcInstance, null);
[C#]
// set value of property: public double Number
numberPropertyInfo.SetValue(calcInstance, 10.0, null);
For your example:
void Main()
{
const int testValue=5;
var test = (Test)Activator.CreateInstance(typeof(Test));
PropertyInfo valuePropertyInfo = typeof(Test).GetProperty("Value");
valuePropertyInfo.SetValue(test, testValue, null);
int value = (int)valuePropertyInfo.GetValue(test, null);
Console.Write(value); //Assert here instead
}
public class Test
{
private int _value;
public int Value {get {return _value;} set{_value=Value;}}
}
the output of the above function is 0 instead of a 5 which is expected. asserting here would have thrown an error.
What do you think about this approach.
Gallio/MbUnit has a contract verifier which does exactly what you are looking for. A typical usage of AccessContract is the following:
public class Foo // Dummy reference type.
{
private readonly int value;
public int Value { get { return value; } }
public Foo (int value)
{
this.value = value;
}
}
public class Bar
{
private Foo foo;
public Bar(string unusedParameter) { }
public Foo Foo // A complex property to be tested!
{
get { return foo; }
set
{
if (value == null)
throw new ArgumentNullException("value");
if (value.Value < 0)
throw new ArgumentOutOfRangeException();
if (value.Value == 666)
throw new ArgumentException("Inferno value strictly forbidden.");
foo = value;
}
}
}
And the test fixture which uses AccessorContract to run various tests on the property.
[TestFixture]
public class BarTest
{
[VerifyContract]
public readonly IContract AccessorTests = new AccessorContract<Bar, Foo>
{
Getter = target => target.Foo,
Setter = (target, value) => target.Foo = value,
ValidValues = { new Foo(123), new Foo(456), new Foo(789) },
AcceptNullValue = false,
DefaultInstance = () => new Bar("Hello"),
InvalidValues =
{
{ typeof(ArgumentOutOfRangeException), new Foo(-123), new Foo(-456) },
{ typeof(ArgumentException), new Foo(666) }
}
};
}
The contract verifier generates the following unit tests:
Have a look at the MbUnit test project for more usage examples.
Edit 1
Is it possible to do this with get/set? Something like the below? This works for me but I am worried I am missing something not to mention all the staticness.
///<summary>
/// Class to track and maintain Heads Up Display information
///</summary>
public static class HUD
{
///<summary>
///Declare variables to store HUD values
///</summary>
private static string _lastName;
private static string _firstName;
private static string _middleName;
private static string _suffix;
private static string _sSN;
private static string _personID;
private static string _masterID;
private static string _enrollmentID;
private static string _planID;
// Store a reference to THE form that holds the HUD and is visible
private static FrmModuleHost _frmHUDHost;
public static string PersonId
{
get { return _personID; }
set
{
FrmHudHost.tbxHUD_PersonID.Text = value;
_personID = value;
}
}
public static string SSn
{
get { return _sSN; }
set
{
FrmHudHost.tbxHUD_SSN.Text = value;
_sSN = value;
}
}
public static string MiddleName
{
get { return _middleName; }
set
{
FrmHudHost.tbxHUD_MiddleName.Text = value;
_middleName = value;
}
}
public static string FirstName
{
get { return _firstName; }
set
{
FrmHudHost.tbxHUD_FirstName.Text = value;
_firstName = value;
}
}
public static string LastName
{
get { return _lastName; }
set
{
FrmHudHost.tbxHUD_LastName.Text = value;
_lastName = value;
}
}
public static string Suffix
{
get { return _suffix; }
set
{
FrmHudHost.tbxHUD_SuffixName.Text = value;
_suffix = value;
}
}
public static string MasterID
{
get { return _masterID; }
set
{
FrmHudHost.tbxHUD_MasterID.Text = value;
_masterID = value;
}
}
public static string EnrollmentID
{
get { return _enrollmentID; }
set
{
FrmHudHost.tbxHUD_EnrollmontPeriod.Text = value;
_enrollmentID = value;
}
}
public static string PlanID
{
get { return _planID; }
set
{
FrmHudHost.tbxHUD_PlanID.Text = value;
_planID = value;
}
}
public static FrmModuleHost FrmHudHost
{
get { return _frmHUDHost; }
set { _frmHUDHost = value; }
}
}
Original Post
I have a class that is responsible for updating a Heads Up Display of current selected member info. My class looks like this -->
public static class HUD
{
///<summary>
///Declare variables to store HUD values
///</summary>
public static string _lastName;
public static string _firstName;
public static string _middleName;
public static string _suffix;
public static string _sSN;
public static string _personID;
public static string _masterID;
public static string _enrollmentPeriod;
public static string _planID;
///<summary>
/// Method to update the display with current information
///</summary>
public static void UpdateHUD (FrmModuleHost frm, params String[] args)
{
frm.tbxHUD_LastName.Text = args[0];
_lastName = args[0];
frm.tbxHUD_FirstName.Text = args[1];
_firstName = args[1];
frm.tbxHUD_MiddleName.Text = args[2];
_middleName = args[2];
frm.tbxHUD_SSN.Text = args[3];
_sSN = args[3];
frm.tbxHUD_PersonID.Text = args[4];
_personID = args[4];
}
}
What I am trying to figure out is how I can tell what args are being passed. What you see below is what is called from the Search Page as that is all that is available at that point. The other 4 values will be loaded 1 at a time on various pages. A person HAS A enrollment which HAS A plan if that helps.
private void GetResults()
{
var lName = getCurrentRowVal("Last Name");
var fName = getCurrentRowVal("First Name");
var pID = getCurrentRowVal("Person ID");
var sSN = getCurrentRowVal("SSN");
var mName = getCurrentRowVal("Middle Name");
HUD.UpdateHUD(FrmWwcModuleHost, lName, fName, mName, sSN, pID);
}
Now when I call this from the Enrollment Page I will want everything to stay and add the EnrollmentID.
private void GetResults()
{
var enrollmentID = getCurrentRowVal("EnrollmentID");
HUD.UpdateHUD(FrmWwcModuleHost, enrollmentID);
}
My question is, How do I do that and know which arg[] index to call and not overwrite the existing values?
Is it as simple as always providing ALL parameters as they are set? So my call from the Enrollment Page would instead look like this -->
private void GetResults()
{
var enrollmentID = getCurrentRowVal("EnrollmentID");
HUD.UpdateHUD(FrmWwcModuleHost, HUD._lastName, HUD._firstName, HUD._middleName, HUD._sSN, HUD._personID, enrollmentID);
}
Thanks for any insights!
You'll really need to ditch the params style call and establish real parameters for your methods. Just create multiple overloads for your most common call signatures.
I did not see a reference to a particular version of .net you are using. Here is how I handle this in .net 3.5.
First create a class for passing the update values in, but make all of the properties nullable (since all of your items are string, they are already nullable). If the values are nullable, add actual property setters, and LastNameChanged properties.
public class UpdateData {
public string LastName { get; set;};
public string FirstName { get; set;};
public string MiddleName { get; set;};
...
}
Now your method signature looks like this:
public static void UpdateHUD (FrmModuleHost frm, UpdateData data)
{
if (!string.IsNullOrEmpty(data.FirstName) {
frm.tbxHUD_LastName.Text = data.FirstName;
_lastName = data.FirstName;
}
if (!string.IsNullOrEmpty(data.LastName) {
frm.tbxHUD_FirstName.Text = data.LastName;
_firstName = data.FirstName;
}
if (!string.IsNullOrEmpty(data.MiddleName) {
frm.tbxHUD_MiddleName.Text = data.MiddleName;
_middleName = data.FirstName;
}
Next is the setting the UpdateData and calling the method:
UpdateHUD(FrmWwcModuleHost, new UpateData{ FirstName = "test1", LastName = "test2", ...});
Final note: you are using a lot of statics here. You might consider changing most of them. Move the static variables to an actual class with properties (but no statics), and reference the class in your code.
Perhaps instead of
params String[] args
you should do
params KeyValuePair<String,String>[] args
where any given param's properies would be assigned something like this:
Key = "Last Name"
Value = "Hare"
Then inside your UpdateHUD method you could check to see what the Key of the parameter was so you would know which value was being passed.
You could also create a separate class to pass in the params array. Something like:
public class HUDParam {
public HUDParam(paramName, paramValue) { /*[init code here...]*/ }
public string Name { get; set; }
public string Value { get; set; }
}
Then:
HUD.UpdateHUD(frm, new HUDParam("FirstName", "Tom"),
new HUDParam("LastName", "Thompson");
In your update method, you can just check the name and set the appropriate value in your HUD.
C# 4.0 has optional params which are much different from the params keyword. Params keyword is literally no different at runtime than if you didn't have the params keyword at all. In other words, you just get an array of values with no way of knowing which are which. Params keyword is just a C# convenience at compile time.
Although I haven't used C# 4.0 optional parameters yet, I imagine they behave similarly to the way VB.NET optional parameters did in that you can specify a default value at the function and that default will be used if the caller doesn't specify it. But the caller still has to indicate (either with missing values or paramName:= syntax) which parameter they are specifying.
In your case I think you're better off using either normal named parameters and passing null when you don't need them, or pass a dictionary/hashtable instead.
You could pass the arguments with a Dictionary where you can assign a value to a certain name.
The cleanest version would be to make a method for each variable.
e.g.
void UpdateLastName(string name)
{
frm.tbxHUD_LastName.Text = _lastName = name;
}
If you can use Framework 4.0, you can use optional and named parameters. Until that time, you will need to pass all the arguments.
But, I think by your question you might misunderstand what's happening slightly. The arguments you send in params are going into the method as an argument. Their scope therefore is the method itself, so you not "overwriting" anything. The array that you used for the first call is gone (out of scope) and the array you use for the second call will have whatever you put in it. Best way to do optional parameters before 4.0 is using multiple method overloads.
If you have a name association with a value but possibly unknown name values this is a candidate for a Dictionary .
Optional parameters involve no less checking than checking a dictionary if a key exists or if a member of a class is null. Since there already exists a primitive for this and it's more flexible I see no reason to use variable parameters or optional parameters.
What I would do is use an ananoymous type (which can be turned into a dictionary at runtime) and then changing the values which are present.
New function definition:
public static void UpdateHUD (FrmModuleHost frm, object args);
And client code:
UpdateHUD(frm, new {
MiddleName = "Jed",
SSN = "..." });
Using the code from Roy Osherove's Blog, this can be turned into a dictionary. The new implementation would be similar to:
var dictionary = MakeDictionary(args);
if ( dictionary.ContainsKey("SSN") ) { _sSN = dictionary["SSN"]; }
Of course, this will all be irrelevant when C# 4.0 comes out.