Rasik
Rasik

Reputation: 2410

How to initialize a property by setting some value without passing anything over a constructor

I have some additional work to do get the value from a string and set to a property As shown in the example.

Here I am putting all the logic to extract a value from a string in a constructor and I have set all the property.

public class CourseModuleView
{

    public CourseModuleView(string str)
    {
        var re = new Regex(@"'(.*?)'");
        var results = Regex.Matches(str, @"'(.*?)'", RegexOptions.Singleline)
                .Cast<Match>()
                .Select(x => x.Groups[1].Value);

        UserId = int.Parse(results.ElementAt(0));
        ComponentType = results.ElementAt(1);
        ModuleId = int.Parse(results.ElementAt(2));
    }
    public int Id { get; set; }
    public int UserId { get; set; }
    public int ModuleId { get; set; }
    public string ComponentType { get; set; }
}

I am calling my constructor as:

//str will have the pattern like this, 
//"The user with id '2209' viewed the 'url' activity with course module id '317'
// but it will be a list of string
var modCompletedResult = allLog
     .Where(x => x.EventName == EventNameMessage.CourseModuleView)
     .Select(x => new CourseModuleView(x.str)
     {
        //other property setting code goes here

     }).ToList();

Sometimes if I want to inject other value in the same constructor (from the different methods) I have to pass both the unrelated value also.

What is the other most appropriate way to set the property while extracting the value from the string without writing all the logic in the constructor?

Upvotes: 0

Views: 1153

Answers (1)

Alvin Stefanus
Alvin Stefanus

Reputation: 2153

public int Id { get; set { this.Id = extractId(value); }}
public int UserId { get; set { this.UserId = extractUserId(value); }}
.....

Then assign it in the select:

var theString = "The user with id '2209' viewed the 'url' activity with course module id '317'.";
var modCompletedResult = allLog
 .Where(x => x.EventName == EventNameMessage.CourseModuleView)
 .Select(x => new CourseModuleView()
 {
    Id = theString,
    UserId = theString,
    ......
 }).ToList();

Sorry im using a phone, quite hard to write code here.


The C# setter and getter is powerful, you can even set other properties when assignning only one property. Example

public int Id { get; 
    set {   
         var extracted = extractAll(value); 
         this.Id = extracted.Id;
         this.UserId = extracted.UserId;
         .......
     } 
}

.Select(x => new CourseModuleView()
 {
    Id = theString, //assign only Id will automatically assign all properties according to the Id setter logic
 }).ToList();

Btw you have to keep the name value in the setter, if not, it will try to find the named variable inside the local scope.


Sorry my mistake, when you assigning property in select, it has to be the same type, Id should be assigned by int.

For your case, you can make a dummy property of type string then apply the setter logic in it.

Example:

public string dummy { get; set { ..... }}

Hope this works for you.

public void SetEverything(string str)
{
    var re = new Regex(@"'(.*?)'");
    var results = Regex.Matches(str, @"'(.*?)'", RegexOptions.Singleline)
            .Cast<Match>()
            .Select(x => x.Groups[1].Value);

    this.UserId = int.Parse(results.ElementAt(0));
    this.ComponentType = results.ElementAt(1);
    this.ModuleId = int.Parse(results.ElementAt(2));
}
public int Id { get; set; }
public int UserId { get; set; }
public int ModuleId { get; set; }
public string ComponentType { get; set; }

public string Setter { get { return ""; } //return empty string 
    set {
        SetEverything(value);
    }
}

Then

var modCompletedResult = allLog
 .Where(x => x.EventName == EventNameMessage.CourseModuleView)
 .Select(x => new CourseModuleView()
 {
    Setter = x.str,
 }).ToList();

Upvotes: 1

Related Questions