Class 属性 — 在 属性 为空时通过扩展方法填充
Class property — filling by Extension method while the Property is null
我有:
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?
}
谷歌搜索没有帮助我,我的母语不是英语,也许我不能问叔叔Google。
使用扩展方法来填充 属性 在我看来是最优雅的赋值方式,但是 虽然在扩展方法中 "c" 变量似乎是初始化并设置好,稍后检查 p.Name 是否为 null - 结果表明它未设置 ...
有什么线索吗?
当你这样做时:
c = new NameClass();
您没有将 NameClass
的实例分配给 Person
对象上的 属性。您正在将它 分配给局部变量 c
。一旦完成赋值,该局部变量就不再与 Person
class.
上的 属性 的引用有任何关系
如果你总是希望 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
构造函数中要求它。 And/or 在 NameClass
构造函数上。
初始化一个对象然后检查它是否有效是两步,但在初始化时要求它是有效的只需要一步。如果不应该允许 "invalid" 对象,则不允许它。
p.Name
是指向null
的引用类型变量。调用 FillIt
方法将 p.Name
的值(即 null
)复制到引用变量 c
。所以,实际上变量 c
和 p.Name
之间没有 link 并且对变量 c
的任何类型的操作都是局部的。
另一方面,如果 p.Name
不是 null
并且指的是内存地址,比如说 0x1111
,那么调用扩展方法会将那个地址复制到变量 c
和对 c
的操作也会影响 p.Name
,因为它们都引用相同的内存地址。
我有:
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?
}
谷歌搜索没有帮助我,我的母语不是英语,也许我不能问叔叔Google。
使用扩展方法来填充 属性 在我看来是最优雅的赋值方式,但是 虽然在扩展方法中 "c" 变量似乎是初始化并设置好,稍后检查 p.Name 是否为 null - 结果表明它未设置 ...
有什么线索吗?
当你这样做时:
c = new NameClass();
您没有将 NameClass
的实例分配给 Person
对象上的 属性。您正在将它 分配给局部变量 c
。一旦完成赋值,该局部变量就不再与 Person
class.
如果你总是希望 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
构造函数中要求它。 And/or 在 NameClass
构造函数上。
初始化一个对象然后检查它是否有效是两步,但在初始化时要求它是有效的只需要一步。如果不应该允许 "invalid" 对象,则不允许它。
p.Name
是指向null
的引用类型变量。调用 FillIt
方法将 p.Name
的值(即 null
)复制到引用变量 c
。所以,实际上变量 c
和 p.Name
之间没有 link 并且对变量 c
的任何类型的操作都是局部的。
另一方面,如果 p.Name
不是 null
并且指的是内存地址,比如说 0x1111
,那么调用扩展方法会将那个地址复制到变量 c
和对 c
的操作也会影响 p.Name
,因为它们都引用相同的内存地址。