C#字段存储在数组中时不保留值

C#字段存储在数组中时不保留值,c#,arrays,string,C#,Arrays,String,在我的程序中,我有大约20个字段。它们都是字符串。现在我还有一个大小为20的字符串数组。我想从存储在此数组中的字符串中顺序初始化这些字段。我不想这样做: field1=数组[0] field2=数组[1] field20=数组[19] 所以我写了一个这样的测试程序,但它不能处理字符串。它只适用于引用类型。有什么办法吗 public class Program { private string name; private string id; private void

在我的程序中,我有大约20个字段。它们都是字符串。现在我还有一个大小为20的字符串数组。我想从存储在此数组中的字符串中顺序初始化这些字段。我不想这样做:

field1=数组[0]

field2=数组[1]

field20=数组[19]

所以我写了一个这样的测试程序,但它不能处理字符串。它只适用于引用类型。有什么办法吗

public class Program
{
    private string name;
    private string id;

    private void Func()
    {
        var array = new[] {name, id};
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = "some string";
        }
    }

    public static void Main(string[] args)
    {
        var p = new Program();
        p.Func();
        Console.WriteLine(p.name); // prints null
    }
}
公共类程序
{
私有字符串名称;
私有字符串id;
私有void Func()
{
var array=new[]{name,id};
for(int i=0;i
关于行为的假设是不正确的

// Create a NEW array with the specified expressions which are evaluated
// immediately (to the current values of the fields)..
var array = new[] {name, id};

// Meaning it is equivalent to this .. note that the field names have
// NOTHING to do with the array object itself.
var array = new[] {(string)null, (string)null};

// Then for each item in the array, assign it a value
// (replacing what was already there anyway)
for (int i = 0; i < array.Length; i++) {
    array[i] = "some string";
}
这是因为
setter(..)
调用前面定义的实际分配给相应成员的操作。对于某些情况,使用这样的查找/代理(使用操作、函数或更复杂的类型)是一种有效的方法,但在不需要时可能应该避免


这也可以通过以下方式完成


反思通常应该是一种“最后手段”。它会丢失静态键入信息,将许多错误推到运行时,并带来性能损失(当然,这可能无关紧要)。有一些非常漂亮的事情可以做(特别是当表达式和注释也被使用时)。。但是,反射是一种神奇的东西,最好在真正需要它之前就离开它。

关于这种行为的假设是不正确的

// Create a NEW array with the specified expressions which are evaluated
// immediately (to the current values of the fields)..
var array = new[] {name, id};

// Meaning it is equivalent to this .. note that the field names have
// NOTHING to do with the array object itself.
var array = new[] {(string)null, (string)null};

// Then for each item in the array, assign it a value
// (replacing what was already there anyway)
for (int i = 0; i < array.Length; i++) {
    array[i] = "some string";
}
这是因为
setter(..)
调用前面定义的实际分配给相应成员的操作。对于某些情况,使用这样的查找/代理(使用操作、函数或更复杂的类型)是一种有效的方法,但在不需要时可能应该避免


这也可以通过以下方式完成


反思通常应该是一种“最后手段”。它会丢失静态键入信息,将许多错误推到运行时,并带来性能损失(当然,这可能无关紧要)。有一些非常漂亮的事情可以做(特别是当表达式和注释也被使用时)。。但是反射是一种神奇的东西,最好在真正需要它之前就离开它。

看看这是否就是你想要实现的目标:

public class Program
{
    private string name;
    private string id;
    private Dictionary<string, int> mapper = new Dictionary<string, int>();
    private String[] array= null;
    public Program()
    {
        mapper.Add("name", 1);
        mapper.Add("id", 2);
    }


    public string Name
    {
        get { return array[mapper["name"]]; }
    }

    public string Id
    {
        get { return array[mapper["id"]]; }
    }

    private void Func()
    {
        array = new[] { name, id };

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = "some string";
        }
    }

    public static void Main(string[] args)
    {
        var p = new Program();
        p.Func();
        Console.WriteLine(p.name); // prints null
    }
}
公共类程序
{
私有字符串名称;
私有字符串id;
私有字典映射器=新字典();
私有字符串[]数组=null;
公共计划()
{
添加(“名称”,1);
添加(“id”,2);
}
公共字符串名
{
获取{返回数组[mapper[“name”]];}
}
公共字符串Id
{
获取{返回数组[mapper[“id”]];}
}
私有void Func()
{
array=new[]{name,id};
for(int i=0;i
看看这是否是您想要实现的目标:

public class Program
{
    private string name;
    private string id;
    private Dictionary<string, int> mapper = new Dictionary<string, int>();
    private String[] array= null;
    public Program()
    {
        mapper.Add("name", 1);
        mapper.Add("id", 2);
    }


    public string Name
    {
        get { return array[mapper["name"]]; }
    }

    public string Id
    {
        get { return array[mapper["id"]]; }
    }

    private void Func()
    {
        array = new[] { name, id };

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = "some string";
        }
    }

    public static void Main(string[] args)
    {
        var p = new Program();
        p.Func();
        Console.WriteLine(p.name); // prints null
    }
}
公共类程序
{
私有字符串名称;
私有字符串id;
私有字典映射器=新字典();
私有字符串[]数组=null;
公共计划()
{
添加(“名称”,1);
添加(“id”,2);
}
公共字符串名
{
获取{返回数组[mapper[“name”]];}
}
公共字符串Id
{
获取{返回数组[mapper[“id”]];}
}
私有void Func()
{
array=new[]{name,id};
for(int i=0;i
您可以通过使用反射来实现这一点,但不应该这样做。在这个配置中:
array[i]=“some string”
您正在丢弃旧的引用,并为
数组[i]
分配一个新值,因此它不会更改
名称
@user2864740的值-好的。你能告诉我如何在数组中为p对象分配所有字段和相应的字符串值吗?为什么?这是正确的初学者问题…你可以通过使用反射来做到这一点,但你不应该这样做。在这个配置中:
array[i]=“some string”
您正在丢弃旧的引用,并为
数组[i]
分配一个新值,因此它不会更改
名称
@user2864740的值-好的。你能告诉我如何在数组中为p对象分配所有字段和相应的字符串值吗?为什么?这是正确的初学者问题…好的,很好。我明白为什么它不起作用了。然而,我想知道一种有效的方法。你知道吗?我理解你的解释。我现在明白为什么它不起作用了。但是我想知道一个解释,它解决了上面用数组的相应值初始化字段的问题。谢谢你提供的详细而清晰的信息。你建议哪一个?反射还是使用代理包装?反射慢吗?不过我只有20个字段。我会直接设置它们,但如果我必须选择一种方法,那就是显式代理/映射。好的,没关系。我明白为什么它不起作用了。然而,我想知道一种有效的方法。你知道吗?我理解你的解释。我现在明白为什么它不起作用了。但是我想知道一个解释,它解决了上面用数组的相应值初始化字段的问题。谢谢你提供的详细而清晰的信息。哪个