I have 2 kind of "Description" for class "People",
Having data with Message:, Priority: and Tag:
Having data without these
List<People> lstPeople = new List<People>
{
new People { Message = "[1y] Message: test messg1 Priority: top Tag: t1" },
new People { Message = "without Message, Priority and Tag desc" }
};
var data = lstPeople;
I would like to extract data after "Message:", "Priority:" and "Tag:" and re-update of each entity of "People" class "Message", "Priority" and "Tag".
Below code does update for "Priority" and "Tag" but not for "Message". What could be the reason?
public class People
{
const string ALERT_DESC_MARKER = "Message:";
const string PRIORITY_MARKER = "Priority:";
const string TAG_MARKER = "Tag:";
private string _description;
private string _tag;
private string _priority;
public string Message
{
get
{
if (_description.Contains(ALERT_DESC_MARKER) && _description.Contains(PRIORITY_MARKER))
return _description ?? GetTextPart(_description, ALERT_DESC_MARKER, PRIORITY_MARKER).Trim();
else
return _description;
}
set
{
_description = value;
}
}
public string Priority
{
get
{
if (_description.Contains(PRIORITY_MARKER) && _description.Contains(TAG_MARKER))
return _priority = GetTextPart(_description, PRIORITY_MARKER, TAG_MARKER).Trim();
else
return _priority;
}
set
{
_priority = value;
}
}
public string Tag
{
get
{
if (_description.Contains(TAG_MARKER))
return _tag = GetTextPart(_description, TAG_MARKER, null).Trim();
else
return _tag;
}
set
{
_tag = value;
}
}
private string GetTextPart(string text, string before, string after)
{
string result = null;
int posBefore = text.IndexOf(before);
if (after != null)
{
int posAfter = text.IndexOf(after);
result = text.Remove(posAfter).Substring(posBefore + before.Length).TrimEnd();
}
else
result = text.Substring(posBefore + before.Length);
return result;
}
}
The problem is in the getter of Message.
As the documentation says:
The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.
So in your case you always return the entire string if _description is not null. Instead you need to return GetTextPart if this condition (_decription != null) is met. Like this:
if (_description.Contains(ALERT_DESC_MARKER) && _description.Contains(PRIORITY_MARKER))
return _description != null ? GetTextPart(_description, ALERT_DESC_MARKER, PRIORITY_MARKER).Trim() : _description;
EDIT:
Here is your test example:
List<People> lstPeople = new List<People>
{
new People { Message = "[1y] Message: test messg1 Priority: top Tag: t1" },
new People { Message = "without Message, Priority and Tag desc" }
};
var data = lstPeople;
foreach (var item in lstPeople)
{
Console.WriteLine(item.Message);
Console.WriteLine(item.Priority);
Console.WriteLine(item.Tag);
}
Output first Item:
test messg1
top
t1
Output second Item:
without Message, Priority and Tag desc
in the second item Priority and Tag are null.
EDIT 2:
Here is the Message getter. The rest of the code that I used to test is identical to the one that you posted. The commented out part is your old/posted version
public string Message
{
get
{
if (_description.Contains(ALERT_DESC_MARKER) && _description.Contains(PRIORITY_MARKER))
return _description != null ? GetTextPart(_description, ALERT_DESC_MARKER, PRIORITY_MARKER).Trim(): _description;
//if (_description.Contains(ALERT_DESC_MARKER) && _description.Contains(PRIORITY_MARKER))
// return _description ?? GetTextPart(_description, ALERT_DESC_MARKER, PRIORITY_MARKER).Trim();
else
return _description;
}
set
{
_description = value;
}
}
Related
Hi anyone know how do i fix this problem. trying to add level on my game.
anyone know which part of the code i need to change
protected SyncFieldString syncTitle = new SyncFieldString();
public virtual string Title
{
get { return title; }
set
{
title = value;
if (IsServer)
syncTitle.Value = value;
}
}
protected SyncFieldString syncLevel = new SyncFieldString();
public virtual string Level
{
get { return level; }
set
{
level = value;
if (IsServer)
syncLevel.Value = value;
}
}
And here some of the code in my level format
if (uiTextLevel != null)
uiTextLevel.text = string.Format(levelFormat, Data == null ? "N/A" : Data.Level.ToString("N0"));
Sorry im just beginner.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace Crystal_Message
{
class Message
{
private int messageID;
private string message;
private ConcurrentBag <Employee> messageFor;
private Person messageFrom;
private string calltype;
public Message(int iden,string message, Person messageFrom, string calltype, string telephone)
{
this.messageID = iden;
this.messageFor = new ConcurrentBag<Employee>();
this.Note = message;
this.MessageFrom = messageFrom;
this.CallType = calltype;
}
public ConcurrentBag<Employee> ReturnMessageFor
{
get
{
return messageFor;
}
}
public int MessageIdentification
{
get { return this.messageID; }
private set
{
if(value == 0)
{
throw new ArgumentNullException("Must have Message ID");
}
this.messageID = value;
}
}
public string Note
{
get { return message; }
private set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Must Have a Message");
}
this.message = value;
}
}
public Person MessageFrom
{
get { return messageFrom; }
private set
{
this.messageFrom = value;
}
}
public string CallType
{
get { return this.calltype; }
private set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentNullException("Please specify call type");
}
this.calltype = value;
}
}
public void addEmployee(Employee add)
{
messageFor.Add(add);
}
public override string ToString()
{
return "Message: " + this.message + " From: " + this.messageFrom + " Call Type: " + this.calltype + " For: " + this.returnMessagefor();
}
private string returnMessagefor()
{
string generate="";
foreach(Employee view in messageFor)
{
generate += view.ToString() + " ";
}
return generate;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
Message testEquals = obj as Message;
if((System.Object)testEquals == null)
{
return false;
}
return (this.messageID == testEquals.messageID) && (this.message == testEquals.message) && (this.messageFor == testEquals.messageFor) && (this.messageFrom == testEquals.messageFrom) && (this.calltype == testEquals.calltype);
}
public bool Equals(Message p)
{
if ((Object)p == null)
{
return false;
}
return (this.messageID == p.messageID) && (this.message == p.message) && (this.messageFor == p.messageFor) && (this.messageFrom == p.messageFrom) && (this.calltype == p.calltype);
}
public override int GetHashCode()
{
unchecked
{
return this.messageID.GetHashCode() * 33 ^ this.message.GetHashCode() * 33 ^ this.messageFor.GetHashCode() * 33 ^ this.messageFrom.GetHashCode() * 33 ^ this.calltype.GetHashCode();
}
}
}
}
I have a Message class where a user could leave a message for more than one person. I have a getter for it, however, is returning a ConcurrentBag<> the way I've done proper practice? If not, how do i return the ConcurrentBag<> so I can loop through it and display it?
ConcurrentBag<T> is an IEnumerable<T>. You can loop through it as usual. However, as this is a thread safe collection, there are performance concerns to using it.
If you want to get rid of the performance impact while looping, call ToArray on it and return the new array instead.
public IEnumerable<Employee> ReturnMessageFor
{
get
{
return messageFor.ToArray();
}
}
It's not clear to me what you are trying to accomplish.
Are you trying to externalize the Bag for all operations? Because that's what you did...
If you want to externalize something you can iterate over you should either return the Bag as IEnumerable or return an array or a list copied from the Bag.
Either way it's safe to iterate over. Might not be the best in terms of performance, but that's another question.
// Option 1
public IEnumerable<Employee> ReturnMessageFor
{
get
{
return messageFor;
}
}
// Option 2
public Employee[] ReturnMessageFor
{
get
{
return messageFor.ToArray();
}
}
Notes:
You might want to make messageFor readonly (in the code you posted it is readonly).
Remember that a ConcurrentBag allows you to safely iterate over a snapshot of the collection in a thread safe manner, but it does not lock the items in the collection.
I want to limit my string, so that you have to put a minimum of 3 chars and a max of 10 chars in. Is this possible in the following code below?
main.cs:
class Program
{
static void Main(string[] args)
{
Something hello = new Something();
string myname;
Something test = new Something();
myname = Console.ReadLine();
test.Name = myname;
}
}
class with properties:
class Okay : IYes
{
private string thename;
public string Name
{
get {return thename;}
set {thename = value;} //what to put here???
}
}
The setter is probably not the best place to check. You should make the check at the point of input:
string myname = "";
while (myname.Length<3 || myname.Length >10)
{
Console.WriteLine("Please enter your name (between 3 and 10 characters");
myname = Console.ReadLine();
}
test.Name = myname;
Obviously you can take some steps to make this more user friendly: maybe a different message after the first failure, some way of getting out of the loop, etc.
Try this:-
public string Naam
{
get { return thename; }
set
{
if (value.Length >= 3 && value.Length <= 10)
thename = value;
else
throw new ArgumentOutOfRangeException();
}
}
class Okay : IYes
{
private string name;
public string Name
{
get { return name; }
set
{
if (value == null) throw new ArgumentNullException("Name");
if (value.Length < 3 || value.Length > 10)
throw new ArgumentOutOfRangeException("Name");
name = value;
}
}
}
You can also truncate the string if it's too long, rather than throwing an exception by just taking (up to) the first 10 characters:
class Okay : IYes
{
private string name;
public string Name
{
get { return name; }
set
{
if (value == null) throw new ArgumentNullException("Name");
if (value.Length < 3) throw new ArgumentOutOfRangeException("Name");
name = string.Join("", value.Take(10));
}
}
}
private static void GenericTester()
{
Okay ok = new Okay {Name = "thisIsLongerThan10Characters"};
Console.WriteLine(ok.Name);
}
// Output:
// thisIsLong
Return the value only when it is available. if I use a condition to check the null condition it is throwing a exception. "saying not all code paths return a value"
internal PinMessage()
{
obj.PinsAvailable.ObserveOn(SynchronizationContext.Current).Subscribe(HandlePinsAvailable);
}
private void HandlePinsAvailable(byte[] pinBytes)
{
pinmesssage = Encoding.ASCII.GetString(pinBytes);
}
internal string GetPinMessage(string AccoutNumber)
{
string pinstring = string.Empty;
obj.SendPinRequest(AccoutNumber);
pinstring = pinmesssage;
return pinstring;
}
private string _pinMessage;
public string pinmesssage
{
get//Not all Code paths return a value
{
if (_pinMessage != null)
return _pinMessage;
}
set { _pinMessage = value; }
}
You are getting this compile error because you don't return anything in the case where _pinMesSafe is null. You need to return something from your Access or in the case when that is true, or throw an exception.
private string _pinMessafe;
public string pinmesssage
{
get {
if (_pinMessafe != null)
return _pinMessafe;
}
set { _pinMessafe = value; }
}
You have to return something when it's being called, you can't just put a method call on hold.
What you could do is force a check yourself:
private string _pinMessafe;
public string pinmesssage
{
get {
return _pinMessafe ?? GetMessage()
}
set { _pinMessafe = value; }
}
In this scenario, GetMessage() would have to take care of returning the message. It's hard to give a more detailed answer with the information you've provided.
You should edit your code to make it more readable (this includes the english spelling errors) and add info if needed.
This is not the "best" practice, but will work and let your consumer wait until the producer has written the variable.
private string _pinMessafe;
object locker = new object();
public string pinmesssage
{
get
{
string x = null;
while(x == null) {
lock(locker) { x = _pinMessafe ; }
Thread.Sleep(1);
}
return x;
}
set { lock(locker) { _pinMessafe = value; } }
}
Why this work like this:
XDocument dataFeed = XDocument.Parse(e.Result);
var guide = from query in dataFeed.Descendants("MaxPayne3")
select new NewGamesClass
{
GameID = (string)query.Element("ID"),
GameTitle = (string)query.Element("Title"),
GameDescription = (string)query.Element("Description"),
GameGuide = (string)query.Element("Guide")
};
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
if (selectedIndex == "0")
GuidesListBox.ItemsSource = guide.Where(ngc => ngc.GameTitle.StartsWith("Feel"));
else if (selectedIndex == "1")
GuidesListBox.ItemsSource = guide.Where(ngc => ngc.GameTitle.StartsWith("Serious"));
But not like this:
if (selectedIndex == "0")
GuidesListBox.ItemsSource = guide.Where(ngc => ngc.GameID.StartsWith("000"));
else if (selectedIndex == "1")
GuidesListBox.ItemsSource = guide.Where(ngc => ngc.GameID.StartsWith("001"));
i want to use the GameID Instead The GameTitle.
Sorry about no XML, too early in the morning for me, lol
Here:
https://dl.dropbox.com/u/27136243/AchivementHunters/XML/GameList.xml
Here is the Class:
public class NewGamesClass
{
string gameID;
string gameTitle;
string gamedescription;
string gameImage;
string gameGuide;
string videoLink;
public string GameID
{ get { return gameID; } set { gameID = value; } }
public string GameTitle
{ get { return gameTitle; } set { gameTitle = value; } }
public string GameDescription
{ get { return gamedescription; } set { gamedescription = value; } }
public string GameImage
{ get { return gameImage; } set { gameImage = value; } }
public string GameGuide
{ get { return gameGuide; } set { gameGuide = value; } }
public string VideoLink
{ get { return videoLink; } set { videoLink = value; } }
}
Most of the <MaxPayne3> nodes do not have a child <ID> node, hence this code:
select new NewGamesClass
{
GameID = (string)query.Element("ID"),
GameTitle = (string)query.Element("Title"),
GameDescription = (string)query.Element("Description"),
GameGuide = (string)query.Element("Guide")
}
will produce mostly nulls for GameID. Then this code:
guide.Where(ngc => ngc.GameID.StartsWith("000"))
will throw NullReferenceException for all those elements
change it to this:
guide.Where(ngc => !String.IsNullOrEmpty(ngc.GameID) && ngc.GameID.StartsWith("000"))
and it should work fine.
Given that we have no data, the only significant difference here is the .GameTitle. vs .GameID.. I'm assuming that "won't work" here means "it throws an exception". The primary exception I can predict there would be NullReferenceException, because .GameID is null, so .GameID.anything is illegal.
Which makes me think that <ID>whatever</ID> doesn't exist at the location you think it does (which will result in .GameID being a null reference). Things to verify:
that it exists there
that the case is correct (ID, Id, id, etc)
that is is an element, not an attribute
that it isn't in a namespace
Update: and here's the problem from the data:
<MaxPayne3>
<Title>Part I Complete - 20G</Title>
<Description>Complete Part I Of The Story</Description>
<Guide>Story related, cannot be missed.</Guide>
<Image>http://www.xbox360achievements.org/images/achievements/925/-K6lMA==.jpg</Image>
<VideoLink/>
</MaxPayne3>
which has no <ID>. There are a lot more like this. So: you need to handle that. A pragmatic check would be:
...blah...guide.Where(ngc => ngc.GameID != null && ngc.GameID.StartsWith("000"));