我不确定我是否能够以某人简单理解的方式制定此问题,因此我们举一个cool
营销示例:
public class Part
{
public MemberType member;
...
}
public class Product
{
public Part part1;
...
}
...
Product product = new Product();
我需要修改公开product
的{{1}}。所以,自然的方法就是写下这样的东西:
part1
现在,一个算法(比如说一种搜索)将通过product.part1 = new Part();
对象并将product
标识为一个有趣的部分并返回对它的引用:
part1
我们可以通过Part Search(Product product)
{
Part part = null;
...
part = product.part1;
...
return part;
}
...
interesting_part = Search(product);
之类的
product
对象
interesting_part
现在,问题:在c / c ++中,如果interesting_part.member = whatever;
是指向Product.part1
的指针而Search返回此指针的地址,我们可以替换{{1}只需为此地址指定新值即可。 AFAIK这不适用于c#reference:
Part
只需创建新对象并复制其对part1
的引用,但不知道成员父(interesting_part = new Part();
对象),我们无法修改(interresting_part
)引用,只是它的内容。我们需要第二级参考。
是否有类似“ref reference”类型的内容可以接受引用地址?在这种假设的情况下,搜索将返回product
并且分配给这样的值会将引用的对象替换为新的。
感谢。
答案 0 :(得分:1)
您可以创建Reference
类
class Reference<T>
{
private Func<T> m_Getter;
private Action<T> m_Setter;
public Reference(Func<T> getter, Action<T> setter)
{
m_Getter = getter;
m_Setter = setter;
}
public T Value
{
get{return m_Getter();}
set{m_Setter(value);}
}
}
现在你可以说
Reference<Part> Search(Product product)
{
Part part = null;
...
part = product.part1;
var reference=new Reference<Part>(()=>product.part, (value)=>product.part1=value);
return refernce;
}
var partReference = Search(product);
partReference.Value = someNewPart;
答案 1 :(得分:0)
在非常类似的情况下,我在每个子对象中保留父对象的引用。简单而有效。
public class Part
{
public MemberType member;
...
public Product parent;
Part(Product p)
{
parent = p;
}
}
public class Product
{
public Part part1;
...
}
答案 2 :(得分:0)
我认为你不能那样做。您需要改变对product
对象的引用,或者添加一些其他引用层。
答案 3 :(得分:0)
所以你需要构建一个Proxy对象。产品将获得对代理的引用,并且可以交换(隐藏)部分。这是一种常见的OO设计模式。当然,Proxy可以将方法调用委托给Part。
答案 4 :(得分:0)
据我所知,没有任何方法可以在不引用对象的情况下更改对象的“父级”。所以我相信你写的问题的正式答案是“不”。
也就是说,有很多方法可以完成任务。最简单的选择是从零件对象添加对父级的引用。你得到的结果如下:
public class Part
{
public Product parentProduct;
public MemberType member;
...
}
现在每当你有一个零件对象时,你也会知道零件所用的产品(如果它确实与零件一起使用)。这不一定是糟糕的编码风格,但肯定存在陷阱。您可以更新产品,但忘记更新该产品中的部件,您正在编码,以便部件有一个产品,但如果该部件有很多产品怎么办?你可以看到它是如何工作的,但它可能变得复杂。
考虑到这一点并使其更通用,您可以将父作为对象类型引用。看起来像是:
public class Part
{
public object parent;
public MemberType member;
...
}
现在,当您想要使用父级时,您可以编写如下内容:
var parentProduct = myPart.parent as Product;
这会将父级转换为产品,或者如果父级不是Product类型,则将分配null。现在,零件可以包含您想要的任何给定类型的父级,并且您可以使模式更加灵活。
我知道人们经常使用的最后一种模式是代表。这允许您传入一个有效修改“搜索”工作方式的函数。说出你真正想做的是搜索,然后以某种方式处理结果,但是你希望这种处理是灵活的(这可能就是你对结果所做的)。在这种情况下,您可以按如下方式使用委托:
// define the delegate
public delegate void ProcessResultDelegate(Product result, Part interestingPart);
// an example search function
public static void RunSearch(IEnumerable<Product> products, ProcessResultDelegate processingHelper)
{
// run the search... then call the processing function
processingHelper(searchResult, interestingPart);
}
当您想要修改例程的行为而不是该例程的返回值时,此模式更有用。
无论如何,希望这些模式有所帮助!
答案 5 :(得分:0)
如果您想更改field
,可以执行此操作,
class Program
{
static void Main(string[] args)
{
var holder = new Holder();
holder.CurrentPart = new Part() { Name = "Inital Part" };
Console.WriteLine(holder.CurrentPart.Name);
TestRef(ref holder.CurrentPart);
Console.WriteLine(holder.CurrentPart.Name);
Console.ReadKey();
}
public static void TestRef(ref Part part)
{
part = new Part() { Name = "changed" };
}
}
public class Part
{
public string Name;
}
public class Holder
{
public Part CurrentPart;
}
这不适用于属性,索引器等。