depending on var count build string - c#

I have List<string> num. Depending on count of num, I need to build a string like:
if num consists of 561924630638
{"formType":"Status", "postDataList":[{"textWithMentions":{"text":"gogogo"}},{"imageData":{"imageIds":["561924630638"], "typeAndSizes":["561924630638,0,300,290"]}}], "news":false, "toStatus":true}
if num consists of 561924630638 and 561924630894
{"formType":"Status", "postDataList":[{"textWithMentions":{"text":"gogogo"}},{"imageData":{"imageIds":["561924630638","561924630894"], "typeAndSizes":["561924630638,0,300,290","561924630894,0,300,290"]}}], "news":false, "toStatus":true}

List<string> _num;
List<string> num
{
get
{
return _num;
}
set
{
_num = value;
// Check the value here and do what you need
if (_num.Contains("561924630638"))
{ }
else if (_num.Contains("561924630638") && _num.Contains("561924630894"))
{ }
}
}

Related

return a value depending on condition

Assuming I have the following extension method:
public static string sampleMethod(this int num) {
return "Valid";
}
how can I terminate sampleMethod and show a messagebox if num > 25 ?
If I try below code,I receive a red underline on the sampleMethod and says not all code path returns a value.
public static string sampleMethod(this int num) {
if(num > 25) {
MessageBox.Show("Integer must not exceed 25 !");
} else {
return "Valid String";
}
}
and if I add throw new Exception("..."); under the MessageBox.Show, everything goes well but the application terminates.
how can I show the MessageBox and terminate the Method instead if the condition is not met ?
Thank you.
Make sure you always return a string (since string is your return value) to all possible outcome/path of your function
public static string sampleMethod(this int num) {
if(num > 25) {
MessageBox.Show("Integer must not exceed 25 !");
return "";
}
return "Valid String";
}
your code didn't work because
public static string sampleMethod(this int num) {
if(num > 25) {
MessageBox.Show("Integer must not exceed 25 !");
// when it go to this block, it is not returning anything
} else {
return "Valid String";
}
}
Suppose you have array of strings with 25 indexes:
public String[] data = new String[25] { /* declare strings here, e.g. "Lorem Ipsum" */ }
// indexer
public String this [int num]
{
get
{
return data[num];
}
set
{
data[num] = value;
}
}
The method should be changed as below if you not want to return any string when the array index exceeds 25:
public static String sampleMethod(this int num) {
if(num > 25) {
MessageBox.Show("Integer must not exceed 25 !");
return String.Empty; // this won't provide any string value
} else {
return "Valid String";
}
}

How to enforce the maximum and minimum number of characters allowed in a string

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

How can i split my List<List<Class>> to store it in another list?

I'm trying to fill my
List<List<Class>> items1 = new List<List<Class>>();
All the Values are in a text file called "TextFileItems1.txt" like this.
2
33
50
0
Termina Especie
1
72
0
1
Termina Especie
2
31
50
0
Termina Especie
2
32
50
0
Termina Especie
2
27
50
0
Termina Especie
2
37
50
0
Termina Especie
2
33
50
0
Termina Especie
2
20
50
0
Termina Especie
2
44
50
0
Termina Especie
2
29
50
0
Termina Especie
And so on ... I have 960 elements
My problem is the main list length has to be equal to a variable called Length1 and the sublist length has to be equal to a variable called Length2, example
Length1 = 40;
Length2 = 24;
My problem is, how can I split the text file in order to insert 40 MainList and 24 SubList into items1?
Class
public class cEspecie
{
private string name;
private int lifetime;
private int movility;
private int deadto;
private int type;
public string Name
{
get
{
return name;
}
set
{
name= value;
}
}
public int Type
{
get
{
return type;
}
set
{
type = value;
}
}
public int LifeTime
{
get
{
return lifetime;
}
set
{
lifetime= value;
}
}
public int Movility
{
get
{
return movility;
}
set
{
movility = value;
}
}
public int DeadTo
{
get
{
return deadto;
}
set
{
deadto = value;
}
}
}
Here's a really simple one using LINQ, a creative for loop, and generators. Here it is on Complify
public static class EnumerationExtensions {
public static IEnumerable<IEnumerable<T>> SplitIntoGroupsOfSize<T>(IEnumerable<T> collection, int ofSize) {
for(
IEnumerable<T> remainingCollection = collection;
remainingCollection.Count() > 0;
remainingCollection = remainingCollection.Skip(ofSize) ) {
yield return remainingCollection.Take(ofSize);
}
}
}
var collection = Enumerable.Range(1, 22).ToArray();
var groups = EnumerationExtensions.SplitIntoGroupsOfSize(collection, ofSize: 4);
var res = String.Join("\n-------------\n", groups.Select(g => String.Join(", ", g) ) );
Console.WriteLine(res);
I would probably make it as an extension method in a real project since that's expected for this sort of thing but complify has problems with these.
With your parameters a recursive solution would also probably work but you know...c# has no tail-call optimization so...
explanation: consider that a for loop is really just a special case of a while loop
for(initial condition; while this is true; do this before each but the first iteration) {}
Turns out that in this case this is very similar to what we need, but not with the standard integer index setup, instead the third condition is simply to track what we values have not yet been returned.
The yield keyword basically is a simpler way of creating an enumerator. In fact, that's exactly what it gets compiled to. so every time a foreach loop (or a Select(), etc) calls enumerator.MoveNext() we run the code until we hit the next yield return.
class Program
{
static void Main(string[] args)
{
List<cEspecie> cEspecieList = new List<cEspecie>();
string[] myEspecieFile = File.ReadAllLines("file.txt");
List<cEspecie> mainList = new List<cEspecie>();
//here you can do the some for the sublist
for (int i = 0; i < myEspecieFile.Length; i=i+5)
{
cEspecie ces = new cEspecie()
{
Name = myEspecieFile[i],
LifeTime = int.Parse(myEspecieFile[i + 1]),
Movility = int.Parse(myEspecieFile[i + 2]),
DeadTo = int.Parse(myEspecieFile[i + 3]),
Type = int.Parse(myEspecieFile[i + 4])
};
mainList.Add(ces);
}
// and then you can iterate through your mainList to add sub list something like this
foreach (var item in mainList)
{
item.cSubEspecieList = mainList;
}
}
}
public class cEspecie
{
private string name;
private int lifetime;
private int movility;
private int deadto;
private int type;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Type
{
get
{
return type;
}
set
{
type = value;
}
}
public int LifeTime
{
get
{
return lifetime;
}
set
{
lifetime = value;
}
}
public int Movility
{
get
{
return movility;
}
set
{
movility = value;
}
}
public int DeadTo
{
get
{
return deadto;
}
set
{
deadto = value;
}
}
//you need only this property in oreder to create sublist
public List<cEspecie> cSubEspecieList
{
get;
set;
}
}
Here is a single LINQ query to create List<List<cEspecie>> with inner list of count Length2:
var result =
File.ReadAllLines("TextFile.txt")
.Select((line, i) => new { Line = line, LineNumber = i })
.GroupBy(a => a.LineNumber / 5,
a => a.Line,
(key, values) => new
{
Number = key,
Class = new cEspecie()
{
LifeTime = int.Parse(values.ElementAt(0)),
Movility = int.Parse(values.ElementAt(1)),
DeadTo = int.Parse(values.ElementAt(2)),
Type = int.Parse(values.ElementAt(3)),
Name = values.ElementAt(4)
}
})
.GroupBy(a => a.Number / Length2,
a => a.Class,
(key, values) => values.ToList())
.ToList();
You will probably set properties with different elements order because I do not know the order.

Compiling class in DLL and referencing it in another project in C#

Hope I'm asking this correctly.
I have this class:
class ListUtilities
{
private List<string> _datalist;
public ListUtilities(List<string> datalist)
{
_datalist = datalist;
}
//Method to calculate age from a date
private int getAge(string bdaystr)
{
DateTime today = DateTime.Today;
DateTime bday = new DateTime(Convert.ToInt32(bdaystr.Substring(0, 4)), Convert.ToInt32(bdaystr.Substring(4, 2)), Convert.ToInt32(bdaystr.Substring(6, 2)));
int age = today.Year - bday.Year;
if (bday > today.AddYears(-age)) age--;
return age;
}
//Method to print the data List
public void printDataList()
{
for (int i = 0; i < _datalist.Count; i++)
{
Console.WriteLine(_datalist.ElementAt(i));
}
}
//Method to calculate and print the ages
public void printAges()
{
List<int> ages = new List<int>();
for (int i = 0; i < _datalist.Count; i++)
{
string s = _datalist.ElementAt(i);
string[] data = s.Split(',');
ages.Add(getAge(data[3]));
}
Console.WriteLine("Ages:");
for (int i = 0; i < ages.Count; i++)
{
Console.WriteLine(ages.ElementAt(i));
}
}
//Method to search by surname
public string searchBySurname(string surname)
{
string res = "";
res = _datalist.Find(delegate(String str)
{
string[] data = str.Split(',');
string sname = data[1];
if (sname == surname)
return true;
else
return false;
});
return res;
}
//Method to search by phone number
public string searchByPhoneNumber(string phone)
{
string res = "";
res = _datalist.Find(delegate(String str)
{
string[] data = str.Split(',');
string phn = data[4];
if (phn == phone)
return true;
else
return false;
});
return res;
}
//Method to search by age
public string searchByAge(int age)
{
string res = "";
res = _datalist.Find(delegate(String str)
{
string[] data = str.Split(',');
int age2 = Convert.ToInt32(getAge(data[3]));
if (age2 == age)
return true;
else
return false;
});
return res;
}
//Method to sort by surname
public int sortBySurname(string x, string y)
{
string[] data_x = x.Split(',');
string sname_x = data_x[1];
string[] data_y = y.Split(',');
string sname_y = data_y[1];
return String.Compare(sname_x, sname_y);
}
//Method to sort by phone number
public int sortByPhoneNumber(string x, string y)
{
string[] data_x = x.Split(',');
int phn_x = Convert.ToInt32(data_x[4]);
string[] data_y = y.Split(',');
int phn_y = Convert.ToInt32(data_y[4]);
return phn_x.CompareTo(phn_y);
}
//Method to sort by age
public int sortByAge(string x, string y)
{
string[] data_x = x.Split(',');
int age_x = Convert.ToInt32(data_x[3]);
string[] data_y = y.Split(',');
int age_y = Convert.ToInt32(data_y[3]);
return age_y.CompareTo(age_x);
}
}
and I want to compile it in a .DLL file. I have tried doing it by the console like this:
csc /target:library /out:MathLibrary.DLL Add.cs Mult.cs
and putting that class in a Class Library project and building it, and I get the DLL file in both cases but the problem comes when I want to use that DLL.
I create a new Project, and I do reference the DLL file, but when I want to use it, this is the problem:
And, seems that there is nothing inside the DLL:
Best regards
class ListUtilities
By default classes are internal and can only be seen from inside the same assembly - make your class public and it should work fine:
public class ListUtilities
Your class needs to be public. By default classes are internal which means they can only be seen inside of the DDLL.
You need to make you class public
public class ListUtilities
as clases are by defualt internal.
On a side note:
You may try to use Visual Studio instead of Command Line which will make things easier for you.

Elegant way to validate values

I have a class with many fields which represents different physical values.
class Tunnel
{
private double _length;
private double _crossSectionArea;
private double _airDensity;
//...
Each field is exposed using read/write property. I need to check on setter that the value is correct and generate exception otherwise. All validations are similar:
public double Length
{
get { return _length; }
set
{
if (value <= 0) throw new ArgumentOutOfRangeException("value",
"Length must be positive value.");
_length = value;
}
}
public double CrossSectionArea
{
get { return _crossSectionArea; }
set
{
if (value <= 0) throw new ArgumentOutOfRangeException("value",
"Cross-section area must be positive value.");
_crossSectionArea = value;
}
}
public double AirDensity
{
get { return _airDensity; }
set
{
if (value < 0) throw new ArgumentOutOfRangeException("value",
"Air density can't be negative value.");
_airDensity = value;
}
}
//...
Is there any elegant and flexible way to accomplish such validation?
Assuming you want this sort of behaviour, you might consider some helper methods, e.g.
public static double ValidatePositive(double input, string name)
{
if (input <= 0)
{
throw new ArgumentOutOfRangeException(name + " must be positive");
}
return input;
}
public static double ValidateNonNegative(double input, string name)
{
if (input < 0)
{
throw new ArgumentOutOfRangeException(name + " must not be negative");
}
return input;
}
Then you can write:
public double AirDensity
{
get { return _airDensity; }
set
{
_airDensity = ValidationHelpers.ValidateNonNegative(value,
"Air density");
}
}
If you need this for various types, you could even make it generic:
public static T ValidateNonNegative(T input, string name)
where T : IComparable<T>
{
if (input.CompareTo(default(T)) < 0)
{
throw new ArgumentOutOfRangeException(name + " must not be negative");
}
return input;
}
Note that none of this is terribly i18n-friendly...
All depends what technology you are using - if you're under MVC you can use Attributes, like this;
http://msdn.microsoft.com/en-us/library/ee256141(v=vs.98).aspx
Here's my version, it's a bit cleaner than Jon's version in some respects:
interface IValidator <T>
{
bool Validate (T value);
}
class IntValidator : IValidator <int>
{
public bool Validate (int value)
{
return value > 10 && value < 15;
}
}
class Int2Validator : IValidator<int>
{
public bool Validate (int value)
{
return value > 100 && value < 150;
}
}
struct Property<T, P> where P : IValidator<T>, new ()
{
public T Value
{
set
{
if (m_validator.Validate (value))
{
m_value = value;
}
else
{
Console.WriteLine ("Error validating: '" + value + "' is out of range.");
}
}
get { return m_value; }
}
T m_value;
static IValidator<T> m_validator=new P();
}
class Program
{
static void Main (string [] args)
{
Program
p = new Program ();
p.m_p1.Value = 9;
p.m_p1.Value = 12;
p.m_p1.Value = 25;
p.m_p2.Value = 90;
p.m_p2.Value = 120;
p.m_p2.Value = 250;
}
Property<int, IntValidator>
m_p1;
Property<int, Int2Validator>
m_p2;
}
Try to use such a method:
public void FailOrProceed(Func<bool> validationFunction, Action proceedFunction, string errorMessage)
{
// !!! check for nulls, etc
if (!validationFunction())
{
throw new ArgumentOutOfRangeException(errorMessage);
}
proceedFunction();
}
Yes, by creating your own validation attributes.
Read this article: Business Object Validation Using Attributes in C#
I will have the decency of NOT copying it here :)
Using the Validator function I mentioned in my comment above, I'd do something like this (untested code):
void textBox_Changed(object sender, EventArgs e) {
submitButton.Enabled = validator();
}
bool validator() {
const string NON_POSITIVE = "Value must be greater than Zero";
bool result = false;
string controlName = "Length";
try {
_length = Convert.ToDouble(txtLength.Text);
if (_length <= 0) throw new Exception(NON_POSITIVE);
controlName = "Cross Section Area";
_crossSectionArea = Convert.ToDouble(txtCrossSectionArea.Text);
if (_crossSectionArea <= 0) throw new Exception(NON_POSITIVE);
controlName = "Air Density";
_airDensity = Convert.ToDouble(txtAirDensity.Text);
if (_airDensity <= 0) throw new Exception(NON_POSITIVE);
result = true; // only do this step last
} catch (Exception err) {
MessageBox.Show(controlName + " Error: " + err.Message, "Input Error");
}
return result;
}
John Skeet probably has a better way, but this works. :)
You can achieve this using classes from System.ComponentModel.DataAnnotations
class Tunnel
{
[Range(0, double.MaxValue, ErrorMessage = "Length must be positive value.")]
public double Length { get; set; }
}
Validation:
var tunnel = new Tunnel { Length = 0 };
var context = new ValidationContext(tunnel, null, null);
Validator.ValidateObject(tunnel, context, true);
Also you can implement your own validation attributes overriding ValidationAttribute class

Categories