Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以与对象初始值设定项相同的方式设置实例的属性_C#_Properties_Initializer - Fatal编程技术网

C# 以与对象初始值设定项相同的方式设置实例的属性

C# 以与对象初始值设定项相同的方式设置实例的属性,c#,properties,initializer,C#,Properties,Initializer,我想要的是有一个,但是对于已经创建的对象的实例。大概是这样的: MyClass myObj = MyClass.NewObj(); //... myObj { prop1 = val1, prop2 = val2, ... prop50 = val50 }; 这比写下以下内容要好得多: myObj.prop1 = val1; myObj.prop2 = val2; //... myObj.prop50 = val50; 因为您将得到一个剩余属性(并且只有属性!)的列表,这些属性尚未给定值(就

我想要的是有一个,但是对于已经创建的对象的实例。大概是这样的:

MyClass myObj = MyClass.NewObj();
//...
myObj { prop1 = val1, prop2 = val2, ... prop50 = val50 };
这比写下以下内容要好得多:

myObj.prop1 = val1;
myObj.prop2 = val2;
//...
myObj.prop50 = val50;
因为您将得到一个剩余属性(并且只有属性!)的列表,这些属性尚未给定值(就像对象初始值设定项一样)。
当前是否存在允许此操作的语法构造?(C#6.0)

我想您正在寻找类似于VB中带有操作符的
。答案是否定的。C#中没有这样的东西。不过,如果确实需要并且同意使用动态对象,可以编写一些变通方法。检查下面的示例:

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{}
            }
        }
    }
} 
公共类程序
{
公共静态void Main(字符串[]args)
{
//你的密码在这里
控制台。WriteLine(“第一:”);
MyClass c=新的MyClass();
c、 集合(新的{Property1=“1”,Property2=“2”,Property4=“4”});
控制台写入线(c);
控制台。WriteLine(“第二:”);
c、 SetWithReflection(新的{Property1=“11”,Property2=“22”,Property4=“44”});
控制台写入线(c);
}
}
公共类MyClass{
公共无效集(动态d){
尝试{Property1=d.Property1;}捕获{}
尝试{Property2=d.Property2;}捕获{}
尝试{Property3=d.Property3;}捕获{}
}
公共字符串属性1{get;set;}
公共字符串属性2{get;set;}
公共字符串属性3{get;set;}
公共重写字符串ToString(){
返回string.Format(@“Property1:{0}
属性2:{1}
物业3:{2},物业1,物业2,物业3);
}                
}
公共静态类扩展{
公共静态void SetWithReflection(此T所有者,动态d){
var dynamicrops=d.GetType().GetProperties();
foreach(dynamicrops中的属性infop){
var prop=typeof(T).GetProperty(p.Name);
如果(prop!=null){
试试{prop.SetValue(owner,p.GetValue(d));}catch{}
}
}
}
} 

这个概念很简单。使用对象初始值设定项创建动态类,然后通过某种方法将属性分配给实例。

正如一些人指出的,已经存在类似的构造,但在VisualBasic()中。目前,C#中没有等效的语句。我们最近看到一些非常有用的东西添加到C#,如自动属性初始值设定项、elvis运算符等。因此,我希望将来会添加实例初始值设定项。

如果已经创建了对象,您如何知道“剩下”要分配的属性?如果它是从头开始初始化的,为什么不使用对象初始值设定项呢?像这样的功能是不连贯的。你的问题的答案是,不,目前没有一个语法结构允许这样做,除非你使用VB.NET(WITH关键字),而且即使这样也不会在intellisense中为你提供未设置的属性,因为intellisense怎么知道?我不在乎对象之前发生了什么,智能感知也不需要知道。相反,它应该只关注初始化块,并消除该块中已经给定值的属性。如果您只需要IntelliSense,那么仍然需要使用对象初始值设定项,然后将其重构回属性分配,然后删除新的
。Resharper至少有这种重构;香草Visual Studio没有。但是,即使在香草VS中,您也可以使用行操作(Alt+Select)将
MyObject.
放在所有属性名称前面。然后用分号替换逗号并去掉块。另一种选择是,根据您的场景,使用T4模板或类似Automapper的东西,完全删除您正在键入的任何样板文件。@Jeroen Mostert所有这些似乎都有点过分,并且它不包括将属性添加到相关类中的情况。使用对象初始值设定项,我可以简单地使用
Ctrl+Space
检查该块中未提及的剩余属性。坦白地说,我不明白为什么人们会否决这一点,因为它可能真的很有用,特别是因为框架构造函数通常是不可访问的,并且对象是通过其他方式创建的。这两种方式都使用匿名类型,它们仍然对我的对象的属性一无所知。我问这个问题的原因是,当我有一个具有很多属性的类(甚至可能是一个框架类)时,很难跟踪其中哪些属性已经设置。您的解决方案不会消除已设置的对象(同样,对象初始值设定项也会这样做,非常感谢)。此外,在创建匿名类型的实例时,我需要知道属性的确切名称,这比简单地使用myObj.prop1=val1还要糟糕;myObj.prop2=val2。。。