我有:
public class NameClass
{
public NameClass(){}
string Name {get; set;}
bool IsValid {get; set;}
}
public class Person
{
public Person() {}
public NameClass Name {get; set;}
}
扩展方法:
public static void FillIt(this NameClass c, string name)
{
if (c == null)
{
c = new NameClass();
}
if (string.IsNullOrEmpty(name) == false)
{
c.IsValid = true;
}
c.Name = name;
}
然后创建Person实例的空格:
private void CreateMyPerson()
{
Person p = new Person();
p.Name.FillIt(txtName.Text);
if (p.Name == null) Response.Write("Ooops, PROBLEM!");
// checking for filled p.Name - IT IS STILL null - WHY?
}
谷歌搜索没有帮助我,我不是母语为英语的人,也许我不能很好地问谷歌叔叔。
使用扩展方法来填充属性在我看来是分配值的最优雅方式,但虽然在扩展方法中" c"变量似乎被初始化并设置正常,稍后在检查p.Name是否为null时 - 它变为未设置 ...
任何线索?
答案 0 :(得分:3)
执行此操作时:
c = new NameClass();
您未在NameClass
对象的属性中分配Person
的实例。您将分配给本地变量c
。完成该分配后,该局部变量不再与Person
类上的属性引用有任何关系。
如果您始终要初始化Name
,请在Person
构造函数中执行此操作:
public Person()
{
this.Name = new NameClass();
}
然后你的扩展方法首先不需要检查null:
public static void FillIt(this NameClass c, string name)
{
if (string.IsNullOrEmpty(name) == false)
{
c.IsValid = true;
}
c.Name = name;
}
由于此版本中永远不会重新分配c
,因此它仍然指向Person
对象上的属性。
虽然取决于你在这里尝试完成的任务,你甚至还需要这种扩展方法吗?如果 Person
有一个名称,您可以在Person
构造函数上要求它。和/或NameClass
构造函数。
初始化一个对象,然后检查它是否有效是两个步骤,但要求它在初始化时有效,只需一步即可。如果"无效"不应该允许对象,只是不允许它。
答案 1 :(得分:2)
p.Name
是一个引用类型变量,指向null
。调用FillIt
方法会将p.Name
(null
)的值复制到引用变量c
。因此,事实上变量c
和p.Name
之间没有任何联系,变量c
上的任何操作都是本地的。
另一方面,如果p.Name
不是null
并且引用内存地址,请说0x1111
,那么调用扩展方法会将该地址复制到变量c
c
上的操作也会影响p.Name
,因为它们都引用相同的内存地址。
答案 2 :(得分:0)
正如其他人所说,为什么它不起作用,我想给你一个替代方案。
基本上你需要类似的东西:
public static void FillIt(this out NameClass c, string name)
但这无效。
替代方案可以是:
public static NameClass FillIt(this NameClass c, string name)
{
if (c == null)
c = new NameClass();
if (string.IsNullOrEmpty(name) == false)
c.IsValid = true;
c.Name = name;
//note: return the object c
return c;
}
并称之为:
Person p = new Person();
//note: set the p.Name
p.Name = p.Name.FillIt(txtName.Text);
你也可以这样做,虽然我不建议同时使用XD:
(p.Name ?? new NameClass()).FillIt(txtName.Text);