Is it possible to add custom attribute on Class, that override all empty string properties? Something like this:
[DefaultValueForEmptyString(Text="N/A")]
public class PersonsDTO
{
public string Name { get; set; }
public string Lastname { get; set; }
public string Address { get; set; }
}
public class DefaultValueForEmptyString
{
public static void MapProperties(object Properties, string text)
{
foreach (var property in Properties)
{
if(string.IsNullOrEmpty(property))
{
property = text // "N/A in this case
}
}
}
}
To resolve a similar problem ages ago I implemented an extension to handle this :
public static string ValueOrDefault(this string value)
{
return string.IsNullOrWhiteSpace(value) ? "N/A" : value;
}
Now you can use this on all your string properties :
var person = new PersonsDTO();
//Prints N/A
Console.WriteLine(person.Name.ValueOrDefault());
That's not really impressive but the job is done.
Another option would be to make a custom string class that implicitly converts from your custom class to string and from a string to your custom class. It's a bit heavy handed, but so is making a custom attribute class.
I made a .NET fiddle showing an example of this here
A copy of the code is below in case .NET fiddle goes away.
using System;
public class DefaultString
{
private const string _default = "N/A";
public DefaultString(string normal)
{
Value = normal;
}
private string _value = _default;
public string Value
{
get
{
return _value;
}
set
{
if (String.IsNullOrEmpty(value))
_value = _default;
else
_value = value;
}
}
public bool IsDefault()
{
return Value == _default;
}
public override string ToString()
{
return Value;
}
public static implicit operator string(DefaultString defaultString)
{
if (defaultString == null)
return _default;
return defaultString.ToString();
}
public static implicit operator DefaultString(string normal)
{
return new DefaultString(normal);
}
}
public class Program
{
public static void Main()
{
DefaultString nullDefault = null;
DefaultString nullConstructorDefault = new DefaultString(null);
DefaultString emptyDefault = String.Empty;
DefaultString emptyConstructorDefault = new DefaultString(String.Empty);
DefaultString abcDefault = "abc";
DefaultString abcConstructorDefault = new DefaultString("abcConstructor");
Console.WriteLine("Default string assigned to null: " + nullDefault);
Console.WriteLine("Default string constructed with null: " + nullConstructorDefault);
Console.WriteLine("Default string assigned empty string: " + emptyDefault);
Console.WriteLine("Default string constructed with empty string: " + emptyConstructorDefault);
Console.WriteLine("Default string assigned \"abc\": " + abcDefault);
Console.WriteLine("Default string constructed with \"abcConstructor\": " + abcConstructorDefault);
}
}
The output should be:
Default string assigned to null: N/A
Default string constructed with null: N/A
Default string assigned empty string: N/A
Default string constructed with empty string: N/A
Default string assigned "abc": abc
Default string constructed with "abcConstructor": abcConstructor
Related
I have a get and set set in class of sportsTeam but in Basketball when I am trying to set inherited parameters it says it says "there is no argument given that corresponds to the required formal paramenter.
I have tried playing with some of the parameters and followed my text book almost exactly. I cannot find what I am missing.
//sportsTeam.cs
public class sportsTeam
{ private string coach;
private int numberOfPlayers;
private string seasonPlayed;
private string field;
private string practiceDays;
public sportsTeam(string inCoach, int inNumberOfPlayers, string
inSeasonPlayed, string inField, string inPracticeDays)
{
coach = inCoach;
numberOfPlayers = inNumberOfPlayers;
seasonPlayed = inSeasonPlayed;
field = inField;
practiceDays = inPracticeDays;
}
public String inCoach
{
get { return coach; }
set { coach = value; }
}
public int inNumberOfPlayers
{
get { return numberOfPlayers; }
set { numberOfPlayers = value; }
}
public String inSeasonPlayed
{
get { return seasonPlayed; }
set { seasonPlayed = value; }
}
public String inField
{
get { return field; }
set { field = value; }
}
public String inPracticeDays
{
get { return practiceDays; }
set { practiceDays = value; }
}
}
//basketball.cs
public class basketball : sportsTeam
{
private String ballSupplier;
private String renetter;
public basketball(string inSeasonPlayed, string inField, string inPracticeDays, string inBallSupplier, string inRenetter)
:base(inSeasonPlayed, inField, inPracticeDays) //Error is here
{
inBallSupplier = ballSupplier;
inRenetter = renetter;
}
}
Your parent class constructor have 5 parameters:
public sportsTeam(string inCoach, int inNumberOfPlayers, string
inSeasonPlayed, string inField, string inPracticeDays)
while when you are calling it form the child/ dervied class you are only providing 3 and there is no constructor overload in your parent class with 3 parameters.
See:
public basketball(string inSeasonPlayed, string inField, string inPracticeDays, string inBallSupplier, string inRenetter)
:base(inSeasonPlayed, inField, inPracticeDays) // 3 parameters while it requires 5
You need to provide all the 5 parameters of constructor or create a constructor overload depending on what is your requirement.
You can define another constructor overload in sportsTeam like following :
public sportsTeam(string inSeasonPlayed,
string inField,
string inPracticeDays)
{
seasonPlayed = inSeasonPlayed;
field = inField;
practiceDays = inPracticeDays;
}
You can read more about Constructors and Inheritance here.
Create this constructor in base class
public sportsTeam(string inSeasonPlayed, string inField, string inPracticeDays)
{
this.inSeasonPlayed = inSeasonPlayed;
this.inField = inField;
this.inPracticeDays = inPracticeDays;
}
Is it possible in C# to collect information in an enum instead of a dedicated class?
Example how it would work in Java:
public enum Action {
JUMP( "JUMP", 1),
CROUCH ("CROUCH", 2),
;
private String animationId;
private int buttonId;
private Action( String animationId, int buttonId) {
this.animationId = animationId;
this.buttonId = buttonId;
}
public String getAnimationId() {
return animationId;
}
public int getButtonId() {
return buttonId;
}
}
You can use enum with attributes:
public enum Action{
[MyValue("JUMP", 1)]
JUMP,
[MyValue("CROUCH", 2)]
CROUCH
}
[AttributeUsage(
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class MyValueAttribute : System.Attribute{
public string Value{get; private set}
public string AnimationId{get; private set;}
public MyValueAttribute(string animationId, string value){
AnimationId = animationId;
Value = value;
}
and you can get value as follows:
public static class EnumExtensions{
public static string GetValue(this Enum value)
{
var type = value.GetType();
var name = Enum.GetName(type, value);
if (name == null) return string.Empty;
var field = type.GetField(name);
if (field == null) return string.Empty;
var attr = Attribute.GetCustomAttribute(field, typeof(MyValueAttribute)) as MyValueAttribute;
return attr != null ? attr.Value: string.Empty;
}
public static string GetAnimationId(this Enum value)
{
var type = value.GetType();
var name = Enum.GetName(type, value);
if (name == null) return string.Empty;
var field = type.GetField(name);
if (field == null) return string.Empty;
var attr = Attribute.GetCustomAttribute(field, typeof(MyValueAttribute)) as MyValueAttribute;
return attr != null ? attr.AnimationId: string.Empty;
}
}
Usage:
Action.JUMP.GetValue();
Action.JUMP.GetAnimationId();
or you can use one method which return for example Tuple with AnimationId and Value
No, but you can use static class fields instead:
public sealed class Action
{
public static readonly Action JUMP = new Action("JUMP", 1);
public static readonly Action CROUCH = new Action("CROUCH", 2);
public string AnimationId { get; }
public int ButtonId { get; }
private Action(String animationId, int buttonId)
{
AnimationId = animationId;
ButtonId = buttonId;
}
public override string ToString() => AnimationId;
}
You could definitely use attributes like suggested. However, you can call .ToString() on an enum value to get its name as a string value, and you can also assign int values to them. By default they are assigned 0-X based on index. However you could do this
public enum Action {
JUMP=1,
CROUCH=2
}
And then to access these values
Action action = Action.JUMP;
int value = (int) action; //Is set to 1
string name = action.ToString(); //Is set to "JUMP"
While this certainly will not work in every case depending on how much you want your enum to store, for the situation you described this is much easier.
I have a class named Person
public class Person
{
string name;
int age;
SampleObject(string name, int age)
{
this.name = name;
this.age = age;
}
public override string ToString()
{
string s = age.ToString();
return "Person: " + name + " " + s;
}
}
I have overridden the ToString() to return the name of the person.
I am using the class in another class:
public class MyClass
{
public int Id {get;set;}
public Person person {get;set;}
}
Now, I want to access the class as
MyClass my = new MyClass();
I want that when I execute my.person, it should return the ToString() value of the person class without explicitly calling the my.person.ToString()
Is it possible and if possible, how can I make this happen.
Thanks
You can create another readonly property
public string PersonName { get {return this.person.ToString();} }
Or add checking for possible null
public string PersonName
{
get
{
return (this.person == null) ? String.Empty : this.person.ToString();
}
}
Based on your comment about setting Name of person by same property
I think approach with separated/specific property will be more maintainable
public string PersonName
{
get
{
return (this.person == null) ? String.Empty : this.person.ToString();
}
set
{
if(this.person == null)
{
this.person = new Person(value, 0);
}
else
{
this.person.Name = value;
}
}
}
I don't understand your question very well. but one of solutions to your question is to use implicit cast.
public class Person
{
string name;
int age;
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
public override string ToString()
{
string s = age.ToString();
return "Person: " + name + " " + s;
}
// here
public static implicit operator string(Person d)
{
return d.ToString();
}
}
public class MyClass
{
public int Id { get; set; }
public Person Person { get; set; }
}
static void Main(string[] args)
{
var myclass = new MyClass();
myclass.Person = new Person("test", 12);
// use like this
string name = myclass.Person;
Console.WriteLine(name);
Console.WriteLine("Press any key to continue.");
Console.ReadLine();
}
You can achieve this with operator overload.
public static implicit operator string(Person p)
{
return p.ToString();
}
If you wish you can implement operator overload in MyClass to so it calls person as well.
public static implicit operator string(MyClass my)
{
return my.person;
}
With this you can do something like
string personString = my;
// or my.person if you only implement it for Person
Also you don't need to have a string variable for the age.
Doing the following will work just fine.
return "Person: " + name + " " + age;
I would suggest to use string.Format though.
return string.Format("Person: {0} {1}", name, age);
Code1
public class Human
{
private string h_name = "";
private string h_gender = "Male";
private int h_age = 0;
public string Name
{
get { return h_name; }
set { h_name = value; }
}
public string Gender
{
get { return h_name; }
set { h_name = value; }
}
public int Age
{
get { return h_age; }
set { h_age = value; }
}
}
Code2
public class Here
{
public static void Main(String[] args)
{
Human hm = new Human();
hm.Name = "Bill";
hm.Gender = "Male";
hm.Age = 20;
}
}
Now, I'd like to use the variable "hm" as String where hm will return the Name property... something like:
string person = hm;
Console.WriteLine(person + " has greeted you!");
What will I do? Should I make an Extension or something?
I overridden the ToString() method, and yes, it works on Console.WriteLine()
but now, I want to store it as string in a string variable
string person = hm;
Console.WriteLine(person);
and I get this
Cannot implicitly convert type 'Human' to 'string'
I also want to use it in my VB.NET program, but it gives me this error when I concatenate it:
Operator '&' is not defined for types 'String' and 'Human'
You can declare an implicit conversion from your type to string using operator overloading. But it's a bad idea. I suggest you to override ToString method in your class instead, then you can just output it like this:
Console.WriteLine(hm + " has greeted you!");
There is also a good documentation on how to override ToString method
How To: Override the ToString Method (C# Programming Guide)
An implicit convention by adding the following to the Human class would work
public static implicit operator string(Human h)
{
return h.Name;
}
Although i think the best way is to override the ToString Method like so
public override string ToString()
{
return Name;
}
You could override the ToString method:
public class Human
{
private string h_name = "";
private string h_gender = "Male";
private int h_age = 0;
public string Name
{
get { return h_name; }
set { h_name = value; }
}
public string Gender
{
get { return h_name; }
set { h_name = value; }
}
public int Age
{
get { return h_age; }
set { h_age = value; }
}
public override string ToString()
{
return Name;
}
}
Override ToString() method.
public class Human
{
public override ToString() { return Name }
private string h_name = "";
private string h_gender = "Male";
private int h_age = 0;
public string Name
{
get { return h_name; }
set { h_name = value; }
}
public string Gender
{
get { return h_name; }
set { h_name = value; }
}
public int Age
{
get { return h_age; }
set { h_age = value; }
}
}
Your code would then look like this:
Console.WriteLine(hm + " has greeted you!");
vb.net answer:
As state by others, you need to define a conversion operator. If you want to support string concatenation then you also need to define the & operator.
Public Class Human
Public Property Name As String
Public Shared Widening Operator CType(value As Human) As String
Return value.Name
End Operator
Public Shared Operator &(left As Human, right As String) As String
Return (left.Name & right)
End Operator
Public Shared Operator &(left As String, right As Human) As String
Return (left & right.Name)
End Operator
Public Overrides Function ToString() As String
Return Me.Name
End Function
End Class
I want to create a class that can set multiple value and not delete the old one that was set already, instead add it and the old value. Here is my sample.
myClass myCls = new myClass();
myCls.setString = "My first string!";
myCls.setString = "My second string!";
myCls.setString = "My third string!";
string printMe = myCls.getString();
Console.WriteLine(printMe);
And when it will output something like;
//My first string!My second string!My third string!
One way to do it would be to have a new property on your myClass
public class myClass
{
private string _setString;
public string setString
{
get
{
return _setString;
}
set
{
AuditTrail += value;
_setString = value;
}
}
public string AuditTrail{get;set;}
}
Then in your main method you'd put:
Console.WriteLine(AuditTrail);
You can try with this class:
public class ValueKeeper {
private List<object> values;
public object Value {
get { return ToString(); }
set { values.Add(value); }
}
public ValueKeeper() {
values = new ArrayList<object>();
}
public override string ToString() {
string result = String.Empty;
foreach(object value in values) result += value.ToString();
return result;
}
}
It can be improved of course, but it would satisfy your needs.
Example
ValueKeeper valueKeeper = new ValueKeeper();
valueKeeper.Value = 1;
valueKeeper.Value = "This is a string";
valueKeeper.Value = someCustomObject;
string str = valueKeeper.Value;
Console.WriteLine(str); //PRINTS OUT "1This is a stringxxxxx"
//Where "xxxx" is the string representation of the custom object
You can create class like this.
class MyClass
{
private string myString;
public string MyString
{
get
{
return myString;
}
set
{
myString += value;
}
}
}
In you Program you can use like this
MyClass c = new MyClass();
c.MyString = "String 1";
c.MyString = "String 2";
Console.WriteLine(c.MyString);
This seems like an odd request but it can be done!
class myClass
{
//Properties
private string privateString;
//Constructor
public myClass()
{
}
//Methods
public void setString(string val)
{
privateString += val;
}
public string getString()
{
return privateString;
}
}
string _entry;
public string Entry
{
get { return _entry; }
set { _entry += value; }
}