C# - 将对象的字段指定为对另一个对象的字段的引用(如指针)



我有两个对象,来自同一类类型。他们都有一处房产(以及私人领域(。有条件地,我想将此属性/字段指定为对同一类的另一个实例的同一属性/字段的引用。

需要注意的是,我的要求是阅读引用的字段。给它写信是一种奖励,不是问题,也没有必要。

我想知道是否可以使用ref字段,并在属性getter中执行一些逻辑操作。

此外,我知道在StackOverflow上有一些关于这方面的问题(这里,这里,这里(,但它们都很旧(所以重复的想法似乎不适用于这里(
现在我们使用C#10.0,并且已经实现了许多不同的ref功能,如ref locals。我试着使用其中的一些,但我失败了。希望有更多知识的人能帮助我找到一种方法。

那么,不使用包装器将一个实例的属性链接到另一个实例,这可能吗??(这是我目前的方法,详细如下(


更多详细信息:

这是我的课(实际上是对它的巨大简化(:

public class Person
{
private string _fullName;
public string FullName { get => _fullName; set => _fullName = value; }
}

假设我有3个这个类的实例。现在,如果我试图将一个属性的值分配给另一个属性,则会简单地复制该值(正如预期的那样。我已经很清楚为什么会这样(:

var person01 = new Person() { FullName = "Steve" };
var person02 = new Person() { FullName = "Mr. S" };
var person03 = new Person() { FullName = "Mister Steve" };
person02.FullName = person01.FullName;
// person02.FullName is "Steve"
person01.FullName = "Mr. Steve Jobs";
// person01.FullName is "Mr. Steve Jobs"
// person02.FullName is "Steve" because the value was only copied.

我理解为什么。但我想知道是否有一些优雅的方法可以做到这一点:

ref person02.FullName = ref person01.FullName;  // not allowed
ref person03.FullName = ref person02.FullName;  // not allowed
person01.FullName = "Mr. Steve Jobs";
// person01.FullName is "Mr. Steve Jobs"
// person02.FullName is "Mr. Steve Jobs"
// person03.FullName is "Mr. Steve Jobs"

因此,这个想法是将一个字段指定为另一个对象的另一个字段的引用。我相信通过房地产是不可能的,因为它实际上是一个";方法";获取并设置私人字段。

所以我做了这个,它有效,但不漂亮:

public class Person
{
private string _fullName;
public string FullName
{
get => (FullName_Reference == null ? _fullName : FullName_Reference.FullName);
set => _fullName = value;
}
public Person FullName_Reference { get; set; }
public Person()
{
_fullName = "";
FullName_Reference = null;
}
}
var person01 = new Person() { FullName = "Steve" };
var person02 = new Person() { FullName = "Mr. S" };
var person03 = new Person() { FullName = "Mister Steve" };
person02.FullName_Reference = person01;
person03.FullName_Reference = person02;
person01.FullName = "Mr. Steve Jobs";
// person01.FullName is "Mr. Steve Jobs"
// person02.FullName is "Mr. Steve Jobs"
// person03.FullName is "Mr. Steve Jobs"

为了找到更优雅的方法,我甚至尝试公开私有字段_fullName(通过返回ref的方法(,但我无法将另一个对象的私有字段(也通过方法(设置为对先前返回的引用对象的引用。它总是复制它的价值。

我不熟悉C#10.0的所有新功能,但您可以通过将名称本身视为对象,并在每个Person实例中引用name对象来实现所需的行为。即将其视为成分

public class Name
{
public string FullName { get; set; }
public Name(string fullName)
{
FullName = fullName;
}
}
public class Person
{
public Name Name { get; set; }
public string FullName => Name.FullName;
public Person(Name name)
{
Name = name;
}
}
var person01 = new Person(new Name("Steve"));
var person02 = new Person(new Name("Mr. S"));
var person03 = new Person(new Name("Mister Steve"));
person02.Name = person01.Name;
person03.Name = person02.Name;
person01.Name.FullName = "Mr. Steve Jobs";
// person01.FullName is "Mr. Steve Jobs"
// person02.FullName is "Mr. Steve Jobs"
// person03.FullName is "Mr. Steve Jobs"

EDIT:处理注释中解释的要求

public class Name
{
public string FullName { get; set; }
private readonly List<Person> _people = new List<Person>();
public Name(string fullName)
{
FullName = fullName;
}
public void Add(Person person)
{
_people.Add(person);
}
public void UpdateNames(Name name)
{
foreach (Person person in _people)
{
person.SetName(name);
}
_people.Clear();
}
}
public class Person
{
private Name _name;
public Name Name
{
get => _name;
set
{
_name.UpdateNames(value);
_name = value;
}
}
public string FullName => Name.FullName;
public Person(Name name)
{
_name = name;
_name.Add(this);
}
public void SetName(Name name)
{
_name = name;
_name.Add(this);
}
}

在我看来,实现您想要的东西的最简单方法是使用Func<字符串>检索参考值:

class Person
{
private Func<string> _fullName;
public string FullName { get => _fullName(); set => _fullName = () => value; }
public void SetFullNameRef(Func<string> value)
{
_fullName = value;
}
}

static void Main(string[] args)
{
var person01 = new Person() { FullName = "Steve" };
var person02 = new Person() { FullName = "Mr. S" };
var person03 = new Person() { FullName = "Mister Steve" };
person02.SetFullNameRef(() => person01.FullName);
person03.SetFullNameRef(() => person02.FullName);
person01.FullName = "Mr. Steve Jobs";
Console.WriteLine(person01.FullName); // Mr. Steve Jobs
Console.WriteLine(person02.FullName); // Mr. Steve Jobs
Console.WriteLine(person03.FullName); // Mr. Steve Jobs
}

或者这样写:

class Person
{
private Func<string> _fullName;
public string FullName { get => _fullName(); set => _fullName = () => value; }
public Func<string> RefFullName { get => () => _fullName(); set => _fullName = () => value(); }
}

static void Main(string[] args)
{
var person01 = new Person() { FullName = "Steve" };
var person02 = new Person() { FullName = "Mr. S" };
var person03 = new Person() { FullName = "Mister Steve" };
person02.RefFullName = person01.RefFullName;
person03.RefFullName = person02.RefFullName;
person01.FullName = "Mr. Steve Jobs";
Console.WriteLine(person01.FullName); // Mr. Steve Jobs
Console.WriteLine(person02.FullName); // Mr. Steve Jobs
Console.WriteLine(person03.FullName); // Mr. Steve Jobs
}

相关内容

最新更新