问题描述
我有一个 struct
存储在 readonly
字段中,嵌套在几个级别的对象中(全部在我无法控制的代码中),我正在一个函数中访问这些对象。例如:
struct Surprise { public readonly int a,b,c; }
struct Gizmo { public readonly Surprise surprise; }
struct Bobble { public readonly Gizmo gizmo; }
struct Thing { public readonly Bobble bobble; }
class Gift { public readonly Thing thing; }
void Function (Gift gift) {
int contrived = gift.thing.bobble.gizmo.surprise.a +
gift.thing.bobble.gizmo.surprise.b +
gift.thing.bobble.gizmo.surprise.c;
}
纯粹是为了避免每次使用时都必须输入 gift.thing.bobble.gizmo.surprise
,我想将其分配给具有较短名称的局部变量。但是,我也不需要复制结构体,所以我想避免这种情况:
void Function (Gift gift) {
{ // (A) this is what i'm trying to not type out:
int contrived = gift.thing.bobble.gizmo.surprise.a +
gift.thing.bobble.gizmo.surprise.b +
gift.thing.bobble.gizmo.surprise.c;
}
{ // (B) i can do this,but i don't *need* to copy,so i'd like to avoid:
Surprise s = gift.thing.bobble.gizmo.surprise;
int contrived = s.a * s.b + s.c;
}
{ // (C) what i *want* to do is something like this:
ref Surprise s = ref gift.thing.bobble.gizmo.surprise;
int contrived = s.a * s.b + s.c;
}
}
但是,似乎不允许使用变体 (C),因此无法编译:
CS0192 A readonly field cannot be used as a ref or out value
(except in a constructor)
我的问题是:有没有办法创建一个局部变量来引用只读值类型字段并且不复制它(或其他一些方法来节省一些输入)?
我是 C# 的新手,来自 C++。如果您熟悉 C++,我基本上是在寻找等效的:
const Surprise &s = gift->thing.bobble.gizmo.surprise;
另外:它甚至会有所作为,还是编译器足够聪明,不会在上面的 (B) 中创建副本?
顺便说一下,经过一番挣扎,我确实想出了这个噩梦:
delegate void Hack (in Surprise s);
void Function (Gift gift) {
((Hack)((in Surprise s) => {
int contrived = s.a + s.b + s.c;
...;
}))(gift.thing.bobble.gizmo.surprise);
}
不过,出于希望显而易见的原因,我对此选项不感兴趣。此外,我实际上不确定这是否甚至避免了副本。
解决方法
扩展方法怎么样。
public static class GiftExtension
{
public static int Sum(this Gift gift)
{
int contrived = gift.thing.bobble.gizmo.surprise.a +
gift.thing.bobble.gizmo.surprise.b +
gift.thing.bobble.gizmo.surprise.c;
return contrived;
}
public static int Sum(this Surprise surprise)
{
int contrived = surprise.a +
surprise.b +
surprise.c;
return contrived;
}
}
然后在你的方法中,你可以有
void Function(Gift gift)
{
{
//(A) was trying to use a pointer to access the memory location,couldn't get it to work!
//unsafe
//{
// Surprise* ps = &(gift.thing.bobble.gizmo.surprise);
//}
}
//(B)
{
int contrived = gift.Sum();
}
{
int contrived = gift.thing.bobble.gizmo.surprise.Sum();
}
}
,
创建一个 readonly
属性来访问您想要的值。
public struct Surprise
{
get
{
return gift.thing.bobble.gizmo.surprise;
}
}