Preferred way to set default values of nullable properties? - c#

I'm in a dilemma. The (reduced) task is to redesign the following data holder class
class Stuff
{
public String SomeInfo { get; set; }
}
to accommodate the demand that null mustn't be returned. I can think of two ways to achieve that and after deep consideration of 15 minutes, I simply can't decide which one is to be preferred.
Approach by constructor.
class Stuff
{
public String SomeInfo { get; set; }
public Stuff() { SomeInfo = String.Empty; }
}
Approach by property.
class Stuff
{
private String _SomeInfo;
public String SomeInfo
{
get { return _SomeInfo ?? String.Empty; }
set { _SomeInfo = value; }
}
}
Note that the creation of the Stuff instances might be done using the constructor as well as initialization, if that's of any significance. As far as I'm informed, there won't be any other restrictions (but you know how the customers' specifications not always reflect the reality).

You can only ensure that null is never returned when you use the property:
class Stuff
{
private String _SomeInfo;
public String SomeInfo
{
get { return _SomeInfo ?? String.Empty; }
set { _SomeInfo = value; }
}
}
The same approach is used by text-controls(e.g. in ASP.NET) where the Text property never returns null but String.Empty.
For example(ILSpy):
// System.Web.UI.WebControls.TextBox
public virtual string Text
{
get
{
string text = (string)this.ViewState["Text"];
if (text != null)
{
return text;
}
return string.Empty;
}
set
{
this.ViewState["Text"] = value;
}
}

Just to add another answer to this, you can also set a default value to a string object in a single statement;
class Stuff
{
private String Something {get; set;} = string.Empty;
}

You can also implement the logic in the setter rather than in the getter, that way your back field always has a valid value
class Stuff
{
private String _SomeInfo = string.Empty;
public String SomeInfo
{
get { return _SomeInfo; }
set
{
if (value != null)
{
_SomeInfo = value;
}
}
}
}

Related

Neo4jClient Node/Relationship Class conventions

Is there a standard naming convention for the properties/methods of a node/relationship class when working with Neo4jClient?
I'm following this link Neo4jClient - Retrieving relationship from Cypher query to create my relationship class
However, there are certain properties of my relationship which i can't get any value despite the relationship having it. While debugging my code, i realized certain properties was not retrieved from the relationship when creating the relationship object.
this is my relationship class
public class Creates
{
private string _raw;
private int _sourcePort;
private string _image;
private int _DestinationPort;
private int _eventcode;
private string _name;
private string _src_ip;
private int _src_port;
private string _dvc;
private int _signature_ID;
private string _dest_ip;
private string _computer;
private string _sourceType;
private int _recordID;
private int _processID;
private DateTime _time;
private int _dest_port;
public string Raw { get { return _raw; } set { _raw = value; } }
public int SourcePort { get { return _sourcePort; } set { _sourcePort = value; } }
public string Image { get { return _image; } set { _image = value; } }
public int DestinationPort { get { return _DestinationPort; } set { _DestinationPort = value; } }
public int Eventcode { get { return _eventcode; } set { _eventcode = value; } }
public string Name { get { return _name; } set { _name = value; } }
public string Src_ip { get { return _src_ip; } set { _src_ip = value; } }
public int Src_port { get { return _src_port; } set { _src_port = value; } }
public string DVC { get { return _dvc; } set { _dvc = value; } }
public int Signature_ID { get { return _signature_ID; } set { _signature_ID = value; } }
public string Dest_ip { get { return _dest_ip; } set { _dest_ip = value; } }
public string Computer { get { return _computer; } set { _computer = value; } }
public string SourceType { get { return _sourceType; } set { _sourceType = value; } }
public int RecordID { get { return _recordID; } set { _recordID = value; } }
public int ProcessID { get { return _processID; } set { _processID = value; } }
public DateTime Indextime { get { return _time; } set { _time = value; } }
public int Dest_port { get { return _dest_port; } set { _dest_port = value; } }
}
This is another class
public class ProcessConnectedIP
{
public Neo4jClient.RelationshipInstance<Pivot> bindto { get; set; }
public Neo4jClient.Node<LogEvent> bindip { get; set; }
public Neo4jClient.RelationshipInstance<Pivot> connectto { get; set; }
public Neo4jClient.Node<LogEvent> connectip { get; set; }
}
This is my neo4jclient query to get the relationship object
public IEnumerable<ProcessConnectedIP> GetConnectedIPs(string nodeName)
{
try
{
var result =
this.client.Cypher.Match("(sourceNode:Process{name:{nameParam}})-[b:Bind_IP]->(bind:IP_Address)-[c:Connect_IP]->(connect:IP_Address)")
.WithParam("nameParam", nodeName)
.Where("b.dest_ip = c.dest_ip")
.AndWhere("c.Image=~{imageParam}")
.WithParam("imageParam", $".*" + nodeName + ".*")
.Return((b, bind, c, connect) => new ProcessConnectedIP
{
bindto = b.As<RelationshipInstance<Creates>>(),
bindip = bind.As<Node<LogEvent>>(),
connectto = c.As<RelationshipInstance<Creates>>(),
connectip = connect.As<Node<LogEvent>>()
})
.Results;
return result;
}catch(Exception ex)
{
Console.WriteLine("GetConnectedIPs: Error Msg: " + ex.Message);
return null;
}
}
This is the method to read the results
public void MyMethod(string name)
{
IEnumerable<ProcessConnectedIP> result = clientDAL.GetConnectedIPs(name);
if(result != null)
{
var results = result.ToList();
Console.WriteLine(results.Count());
foreach (ProcessConnectedIP item in results)
{
Console.WriteLine(item.Data.Src_ip);
Console.WriteLine(item.bindto.StartNodeReference.Id);
Console.WriteLine(item.bindto.EndNodeReference.Id);
Console.WriteLine(item.connectto.StartNodeReference.Id);
Console.WriteLine(item.connectto.EndNodeReference.Id);
Node<LogEvent> ans = item.bindip;
LogEvent log = ans.Data;
Console.WriteLine(log.Name);
Node<LogEvent> ans1 = item.connectip;
LogEvent log1 = ans1.Data;
Console.WriteLine(log1.Name);
}
}
}
Somehow, i'm only able to populate the relationship object with src_ip/src_port/dest_ip/dest_port values. the rest are empty.
Is there any possible reason why? I've played with upper/lower cases on the properties names but it does not seem to work.
This is the section of the graph im working with
This is the relationship properties sample:
_raw: Some XML dataSourcePort: 49767Image: C:\Windows\explorer.exeDestinationPort: 443EventCode: 3Name: Bind
IPsrc_ip: 172.10.10.104dvc: COMPUTER-NAMEsrc_port:
49767signature_id: 3dest_ip: 172.10.10.11Computer:
COMPUTRE-NAME_sourcetype:
XmlWinEventLog:Microsoft-Windows-Sysmon/OperationalRecordID:
13405621ProcessId: 7184_time: 2017-08-28T15:15:39+08:00dest_port: 443
I'm not entirely sure how your Creates class is ever populated, in particular those fields - as your Src_port property doesn't match the src_port in the sample you provided (case wise).
I think it's probably best to go back to a super simple version. Neo4jClient will map your properties to the properties in the Relationship as long as they have the same name (and it is case-sensitive).
So start with a new Creates class (and use auto properties - it'll make your life a lot easier!)
public class Creates
{
public string Computer { get; set; }
}
Run your query with that and see if you get a result, then keep on adding properties that match the name and type you expect to get back (int, string etc)
It seems that i have to give neo4j node/relationship property names in lowercase and without special characters at the start of the property name, in order for the above codes to work.
The graph was not created by me at the start thus i had to work on it with what was given. I had to get the developer who created the graph to create the nodes with lowercases in order for the above to work.

Modify multiple string fields

I have the following code:
class SearchCriteria
{
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
// ... around 20 fields follow
public void Trim()
{
if( ! String.IsNullOrEmpty( Name ) )
{
Name = Name.Trim();
}
if( ! String.IsNullOrEmpty( Email ) )
{
Email = Email.Trim();
}
// ... repeat for all 20 fields in the class.
}
}
I want to write one function that will properly trim the fields, something like:
public void Trim()
{
Trim( Name );
Trim( Email );
// ...
}
private static void Trim( ref string field )
{
if( ! String.IsNullOrEmpty( field ) )
{
field = field.Trim();
}
}
Of course, this is not permitted in C#.
One option I have is to write a helper and use reflection.
Is there another way I can achieve this (reflecting on so many properties will deffinitely have a performance hit on that particular scenario and I can't afford that)?
If you already have the code, what are you asking? It's readable and efficient. But maybe it would be better to let the properties already trim the passed value in the first place.
class SearchCriteria
{
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value == null ? null : value.Trim(); }
}
private string _Email;
public string Email
{
get { return _Email; }
set { _Email = value == null ? null : value.Trim(); }
}
private string _Company;
public string Company
{
get { return _Company; }
set { _Company = value == null ? null : value.Trim(); }
}
// ... around 20 fields follow
}
Even if you could use a reflection approach. Consider that this code is always difficult to understand and to maintain. And it will silently trim properties even if they should not be trimmed. For example if another developer extends this class.
public void Trim()
{
Name = Trim( Name );
Email = Trim( Email );
// ...
}
private string Trim(string field )
{
if( ! String.IsNullOrEmpty( field ) )
field = field.Trim();
return field;
}
EDIT:
try also to apply Trim fuction in setters of properties
class SearchCriteria
{
private string Trim(string field)
{
if( ! String.IsNullOrEmpty( field ) )
field = field.Trim();
return field;
}
private string _name;
public string Name
{
get { return _name; }
set { _name = Trim(value); }
}
private string _email;
public string Email
{
get { return _email; }
set { _email = Trim(value); }
}
// ... other string properties
// no public void Trim() method
}
Seems overkill .. saved the time in Trim(), wasted the time in field declaration
class SearchCriteria
{
private Dictionary<string, string> _internalValues = new Dictionary<string, string>();
public string Name { get { return _internalValues.ContainsKey("Name") ? _internalValues["Name"] : null; } set { _internalValues["Name"] = value; } }
....
public void Trim()
{
foreach (var entry in _internalValues)
{
if (!string.IsNullOrEmpty(entry.Value)) _internalValues[entry.Key] = entry.Value.Trim();
}
}
}
I prefer this style, the duplication is unavoidable to maintain readability, but this will save some screen space
class SearchCriteria
{
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
public void Trim()
{
if(!String.IsNullOrEmpty(Name)) Name = Name.Trim();
if(!String.IsNullOrEmpty(Email)) Email = Email.Trim();
if(!String.IsNullOrEmpty(Company)) Company = Company.Trim();
}
}
void Main()
{
var criteria = new SearchCriteria();
criteria.Email = "thing ";
Console.WriteLine(criteria.Email.Length);
criteria.Trim();
Console.WriteLine(criteria.Email);
Console.WriteLine(criteria.Email.Length);
}
If you weren't using auto properties you could just use a ref. I agree it is by no means optimal.
class SearchCriteria
{
private string _name;
public string Name { get { return _name; } set { _name = value; }}
public string Email { get; set; }
public string Company { get; set; }
// ... around 20 fields follow
void Trim(ref string str)
{
if (!String.IsNullOrEmpty(str))
{
str = str.Trim();
}
}
public void Trim()
{
Trim(ref _name);
// ... repeat for all 20 fields in the class.
}
}
Just out of completion. I don't know if this is a good way. But you can use as Tim Schmelter said reflection. But as he also pointed out the code is harder to maintain and if someone extend it might be problems. But here is an example of how you could do it:
class SearchCriteria
{
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
// ... around 20 fields follow
public void Trim()
{
typeof(SearchCriteria).GetProperties()
.Where (w =>w.PropertyType==typeof(string))
.ToList().ForEach(f=>
{
var value=f.GetValue(this);
if(value!=null && !string.IsNullOrEmpty(value.ToString()))
{
f.SetValue(this,value.ToString().Trim(),null);
}
});
}
}
You can amend your code as follows to
public void Trim()
{
Name = Trim(Name);
Email = Trim(Email);
// ...
}
private static void Trim(string field)
{
if( ! String.IsNullOrWhiteSpace( field ) )
{
field = field.Trim();
}
return field;
}
You cannot pass a property by reference, and the method String.IsNullOrEmpty() will consider white-space as non-empty, so I have used String.IsNullOrWhiteSpace().
Reflection will obviously be not the most performant solution, but with some modifications and caching it still can be used.
Here is the reflection helper that will allow you to create collection of mutator delegates and cache it inside of your class:
public static class ReflectionHelper
{
public static IEnumerable<PropertyInfo> GetPropertiesOfType<THolder, TPropType>()
{
return typeof(THolder).GetPropertiesOfType(typeof(TPropType));
}
public static IEnumerable<PropertyInfo> GetPropertiesOfType(this Type holderType, Type propType)
{
if (holderType == null)
throw new ArgumentNullException("holderType");
if (propType == null)
throw new ArgumentNullException("propType");
return holderType
.GetProperties()
.Where(prop =>
prop.PropertyType == propType);
}
public static IEnumerable<Action<Func<TPropType, TPropType>>> CreateMutators<THolder, TPropType>(THolder holder)
{
if (holder == null)
throw new ArgumentNullException("holder");
return holder.GetType()
.GetPropertiesOfType(typeof(TPropType))
.Select(prop =>
new
{
getDelegate = (Func<TPropType>)Func.CreateDelegate(
typeof(Func<TPropType>),
holder,
prop.GetGetMethod()),
setDelegate = (Action<TPropType>)Action.CreateDelegate(
typeof(Action<TPropType>),
holder,
prop.GetSetMethod())
})
.Select(accessor =>
(Action<Func<TPropType, TPropType>>)((mutate) =>
{
var original = accessor.getDelegate();
var mutated = mutate(original);
accessor.setDelegate(mutated);
}))
.ToArray();
}
}
Class code - you cache the mutators and use them inside the Trim method:
class SearchCriteria
{
public SearchCriteria()
{
this.Name = "adsfasd ";
this.Email = " adsfasd ";
this.Company = " asdf adsfasd ";
this.stringMutators = ReflectionHelper.CreateMutators<SearchCriteria, String>(this);
}
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
// ... around 20 fields follow
private IEnumerable<Action<Func<String, String>>> stringMutators;
private String TrimMutate(String value)
{
if (String.IsNullOrEmpty(value))
return value;
return value.Trim();
}
public void Trim()
{
foreach (var mutator in this.stringMutators)
{
mutator(this.TrimMutate);
}
}
public override string ToString()
{
return String.Format("Name = |{0}|, Email = |{1}|, Company = |{2}|",
this.Name,
this.Email,
this.Company);
}
}
Main code:
var criteria = new SearchCriteria();
Console.WriteLine("Before trim:");
Console.WriteLine(criteria);
Console.WriteLine("After trim:");
criteria.Trim();
Console.WriteLine(criteria);
P.S.: However it is not very direct or clear solution, so I'd recommend to go with "smart" setter(getters) as it is described in other answers. Or, perhaps, you can try some Aspect Oriented Programming approach.

Asp.Net C# Object Related Ques

I am new to Asp .net C#. i have question about objects and inheritance.
if i have parent class (Base-Table) that have 2 child classes (Credit-Card-Table , Bank-Account-Table) i have fun. in another class that take an object from the base-table class.
my problem is i want to know if the Base-table is Credit-card or Bank-account ?!
class BaseTable
{
string date;
public string Date
{
get { return date; }
set { date = value; }
}
string description;
public string Description
{
get { return description; }
set { description = value; }
}
}
class CreditCardTable:BaseTable
{
string Amount;
public string amount
{
get { return Amount; }
set { Amount = value; }
}
string Type;
public string type
{
get { return Type; }
set { Type = value; }
}
}
class BankAccountTable:BaseTable
{
string Refr;
public string Ref
{
get { return Refr; }
set { Refr = value; }
}
string debit;
public string Debit
{
get { return debit; }
set { debit = value; }
}
string credit;
public string Credit
{
get { return credit; }
set { credit = value; }
}
}
3 options:
use is, as or GetType() to explicitly check the type of an instance you have been given, to test it against some known types
if(obj is CreditCardTable) {...} else ...
add a virtual or abstract method to the base-type, and use that instead of ever having to worry about which it is (since it will automatically invoke the most derived override)
obj.SomeMethod();
add a discriminator - perhaps a virtual enum property to the BaseTable which all derived types return a different value from, and switch on that discriminator:
switch(obj.Type) { ... }

System.StackOverflowException was unhandled

Please help, I'm confused I do not know why the error logs
System.StackOverflowException was unhandled.
I keep getting an error on set LekID.
How would I that fix?
Here is the code:
public Lager(long lekID, string lek, string proizvojdac, int kolicina, double cena)
{
LekID = lekID;
Lek = lek;
Proizvodjac = proizvojdac;
Kolicina = kolicina;
Cena = cena;
}
public long LekID
{
get { return LekID; }
set { LekID = value; }
}
public string Lek
{
get { return Lek; }
set { Lek = value; }
}
public string Proizvodjac
{
get { return Proizvodjac; }
set { Proizvodjac = value; }
}
public int Kolicina
{
get { return Kolicina; }
set { Kolicina = value; }
}
public double Cena
{
get { return Cena; }
set { Cena = value; }
}
public long LekID
{
get { return LekID; }
set { LekID = value; }
}
This (and the other properties) cause a StackOverflowException, since you are assigning value to LekID over and over again.
You should add a field to the property and store the value there:
private long _lekID;
public long LekID
{
get { return _lekID; }
set { _lekID = value; }
}
You should give different names to your private variables and to your properties. Otherwise, your property is calling itself when you access it.
Example:
long _lekID;
public long LekID
{
get { return _lekID; }
set { _lekID = value; }
}
Or simply:
public long LekID { get; set; }
The properties are calling themself. Try changing your properties like this:
public string Lek
{
get;
set;
}
You're calling the Lek property recursively in both the setter and the getter
Either introduce a backing field:
private string lek;
public string Lek
{
get { return this.lek; }
set { this.lek = value; }
}
or use an Automatic Property:
public string Lek
{
get; set;
}
Marking this community wiki as it is only an aside, but none of this would have happened if you'd been sufficiently lazy (that is often a virtue in programming, not a vice):
public long LekID {get;set;}
public string Lek {get;set;}
public string Proizvodjac {get;set;}
public int Kolicina {get;set;}
public double Cena {get;set;}
less typing; no errors; and you've correctly exposed the API as properties so you can add validation / side-effects later if you need, and it'll work with binding APIs (which don't usually love fields).
Try using code snippet like prop/ propfull,
the snippets will create the properties code automaticly

StackOverflowException on a huge class

So, I got to work on this huge project. And the is this HUGE class with hundreds of variables and methods and lots of partial classes.
interface IBusinessReturn
{
string variableOne { get; set; }
string variableTwo { get; set; }
string variableHundred { get; set; }
//a lot more...
}
public partial class BusinessTransaction : IBusinessReturn
{
private string _variableOne;
public string variableOne
{
get { return variableOne; }
set { _variableOne= value; }
}
private string _variableTwo;
public string variableTwo
{
get { return variableTwo; }
set { _variableTwo = value; }
}
private string _variableHundred;
public string variableHundred
{
get { return variableHundred; }
set { _variableHundred = value; }
}
// And so it goes on till hundreds...
}
And lots of other partials that goes like this:
public partial class BusinessTransaction: IBusinessTransaction238
{
//Lots of methods
}
The problem is: It is all working except for some new variables I declared. (varOne and Two, in the example above). When I try to set any value to these var I got a StackOverflowException. I'm 100% sure they're declared just like every other.
This is how i'm calling:
BusinessTransaction v763 = new BusinessTransaction();
v763.variableHundred = "Hi"; //working
v763.variableOne = "Hello"; //StackOverflow HERE.
I just can't see any reason for why this is happening, and I only hope you can tell me if this have something to do with the huge amount of methods and variables on this class..
Look at your getter - no underscores for any of them. You're causing an infinite loop.
public string variableOne
{
get { return variableOne; }
set { _variableOne= value; }
}
It should return private member, not itself.
Should be
public string variableOne
{
get { return _variableOne; // error was here
}
set { _variableOne= value; }
}

Categories

Resources