-1

What i'd like is having an object initializer, but for an instance of object that has already been created. Something like this:

MyClass myObj = MyClass.NewObj();
//...
myObj { prop1 = val1, prop2 = val2, ... prop50 = val50 };

This would be much better than writing:

myObj.prop1 = val1;
myObj.prop2 = val2;
//...
myObj.prop50 = val50;

because you'd get a list of remaining properties (and only properties!) that haven't already been given value (just like with object initializer). Is there a syntax construct that allows this currently? (C# 6.0)

Community
  • 1
  • 1
  • 1
    If the object has already been created, how would you know what properties are "left" to assign? If it's being initialized from scratch, why *wouldn't* you use an object initializer? A feature like this would not be coherent. – Jeroen Mostert Jul 25 '17 at 12:18
  • The answer to your question is, no, there isn't a syntax construct that allows this currently, unless you're using VB.NET (the WITH keyword) - and even that won't provide you with unset properties in intellisense, because how would the intellisense know? – J. Steen Jul 25 '17 at 12:20
  • I don't care what has happened to the object before, intellisense doesn't need to know either. Instead, it should just focus on initialization block, and eliminate the properties that have already been given value **in that block**. – Arctic_Avenger Jul 25 '17 at 12:45
  • If all you want is IntelliSense, then stick in an object initializer anyway, then refactor it back to property assignments, then remove the `new`. Resharper has this refactoring, at least; vanilla Visual Studio doesn't. However, even in vanilla VS you can use a line operation (Alt+Select) to put `MyObject.` in front of all property names. Then replace the commas with semicolons and get rid of the block. Another option is to eliminate whatever boilerplate you're typing altogether, depending on your scenario, with a T4 template or something like Automapper. – Jeroen Mostert Jul 25 '17 at 13:17
  • @Jeroen Mostert All of that seems a bit excessive, and it doesn't cover cases when properties are added to the class in question. With object initializer, i can simply use `Ctrl + Space` to check for remaining properties that aren't mentioned in that block. Frankly, i don't get why people downvoted this, as it may be really usefull, especially because framework constructors are often not accessible, and objects get created in other ways. – Arctic_Avenger Jul 25 '17 at 14:20
  • You can always [propose it](https://github.com/dotnet/roslyn/issues). But since it's essentially Visual Basic's `With`, people probably have already proposed it (since this discussion is [very old](https://stackoverflow.com/questions/481725/with-block-equivalent-in-c)), I just can't find the issue. Downvotes should be based on the question, not as votes for or against a feature, but people can (and do) downvote for any reason. – Jeroen Mostert Jul 25 '17 at 14:42
  • The fact that something like this exists in VB makes it even more valid to ask if it exists in C#. But it's far easier to downvote than to actually think about what is being asked. – Arctic_Avenger Jul 25 '17 at 14:50

2 Answers2

0

I think you are looking for something like with operator in VB. The answer is no. There is no such thing in C#. Although you can code some workarounds if you really need and if you agree to use dynamic objects. Check example below:

public class Program
{
    public static void Main(string[] args)
    {
        //Your code goes here
        Console.WriteLine("First:");
        MyClass c = new MyClass();
        c.Set(new {Property1="1", Property2="2", Property4="4"});
        Console.WriteLine(c);
        Console.WriteLine("Second:");
        c.SetWithReflection(new {Property1="11",Property2="22", Property4="44"});
        Console.WriteLine(c);

    }
}
public class MyClass{
    public void Set(dynamic d){
        try{ Property1=d.Property1;}catch{}
        try{ Property2=d.Property2;}catch{}
        try{ Property3=d.Property3;}catch{}
    }

    public string Property1{get;set;}
    public string Property2{get;set;}
    public string Property3{get;set;}
    public override string ToString(){
        return string.Format(@"Property1: {0}
Property2: {1}
Property3: {2}", Property1,Property2,Property3);
    }                
}
public static class Extensions{
    public static void SetWithReflection<T>(this T owner, dynamic d){
        var dynamicProps = d.GetType().GetProperties();
        foreach(PropertyInfo p in dynamicProps){
            var prop = typeof(T).GetProperty(p.Name);
            if(prop!=null){
                try{ prop.SetValue(owner, p.GetValue(d)); } catch{}
            }
        }
    }
} 

The concept is simple. Use Object initializer to create dynamic class and than assign properties to your instance via some method.

Pablo notPicasso
  • 3,031
  • 3
  • 17
  • 22
  • Both ways use anonymous types, that still know nothing about the properties of my object. The reason i asked this question is when i have a class with a lot of properties (maybe even a framework class), it gets hard to track which of them have been set. Your solution doesn't eliminate the ones that have been set (again, object initializer does this, and it's greatly appreciated). Furthermore, i need to know the exact names of properties when making an instance of anonymous type, which is even worse than simply using myObj.prop1 = val1; myObj.prop2 = val2; ... – Arctic_Avenger Jul 25 '17 at 13:12
0

As some have pointed out, there already exists a similar construct, but in VisualBasic (VB With). Currently, there isn't an equivalent statement in C#. We've seen lately some very useful things added to C#, like auto-property initializer, elvis operator etc. so i'm hoping instance-initializer will be added in the future.

Community
  • 1
  • 1