C# 通过引用或变通方法存储对象 我在C++中建立了一个游戏的内在逻辑,它来自C++。这是我在翻译中可能丢失的东西。

C# 通过引用或变通方法存储对象 我在C++中建立了一个游戏的内在逻辑,它来自C++。这是我在翻译中可能丢失的东西。,c#,C#,我有一个对象,可以计算它提供的奖金并将其作为整数值返回。计算是动态的,可以根据各种变量进行更改 public class Ability: Buffable { public string abbr { get; private set; } public Ability(string name, string abbr, uint score) : base(name, score) { this.ab

我有一个对象,可以计算它提供的奖金并将其作为整数值返回。计算是动态的,可以根据各种变量进行更改

    public class Ability: Buffable
    {

        public string abbr { get; private set; }

        public Ability(string name, string abbr, uint score) : base(name, score)
        {
            this.abbr = abbr;
        }

        // Ability Modifier
        // returns the ability modifier for the class.
        public int Ability_modifier()
        {
            const double ARBITARY_MINUS_TEN = -10;
            const double HALVE = 2;
            double value = (double)this.Evaluate();
            double result = (value + ARBITARY_MINUS_TEN) / HALVE;

            // Round down in case of odd negative modifier
            if (result < 0 && ((value % 2) != 0))
            {
                result--;
            }
            return (int)result;
        }
公共职业能力:可Buffable
{
公共字符串abbr{get;private set;}
公共能力(字符串名称、字符串缩写、uint分数):基础(名称、分数)
{
this.abbr=abbr;
}
//能力调节剂
//返回类的能力修饰符。
公共整数能力_修饰符()
{
常数双任意值减去十=-10;
常数双减半=2;
double value=(double)this.Evaluate();
双结果=(值+任意值减十)/减半;
//如果是奇数负修饰符,则向下舍入
如果(结果<0&((值%2)!=0))
{
结果--;
}
返回(int)结果;
}
然后我有了另一个对象,Skill,它应该知道这个奖金,并将其添加到它的计算中。我想通过引用将一个能力传递到Skill的构造函数中,然后存储该引用,这样,如果该能力改变了计算,那么计算也会改变。显然,存储引用是一个禁忌在C#中

是否有一种变通的方法来解决这个问题,或者有一种替代的方法来解决这个问题,而我的指针泛滥的头脑并没有考虑这个问题?我非常希望不必每次都将这个能力传递给评估技能的函数,因为引用的函数在构造之后永远不会更改。

在C#中,有引用类型和v值类型。所有非值类型的对象都是通过引用传递的,所以引用应该没有问题。只要传递它,它就会通过引用传递

显然,存储引用在C#中是禁忌的,这是一个明显的问题

绝对不是。引用存储在所有地方。您在这里执行此操作,例如:

this.abbr = abbr;
System.String
是一个类,因此是一个引用类型。因此
abbr
的值是一个引用

我强烈怀疑您误解了引用类型在C#中的工作方式。如果您记住了对对象的引用,那么对对象的更改将通过引用可见。但是,对复制的原始表达式的更改将不可见

例如,使用
StringBuilder
作为方便的可变引用类型:

StringBuilder x = new StringBuilder("abc");

// Copy the reference...
StringBuilder y = x;

// This changes data within the object that x's value refers to
x.Append("def");

// This changes the value of x to refer to a different StringBuilder
x = new StringBuilder("ghi");

Console.WriteLine(y); // abcdef

有关更多详细信息,请参阅我的文章。

我对您的代码了解不够,无法给出一个具体的示例,但方法是传入lambda委托,例如
()=>object.property
,而不是:
object.property

不,对象不是通过引用传递的-引用是通过值传递的(默认情况下)。对于
ref
参数,有真正的按引用传递,它可以应用于引用类型或值类型的参数。这取决于您对术语“按引用传递”的定义,这是有争议的。我经常看到的一个有用定义是“如果一个函数修改了一个值,当通过引用传递时,修改也会出现在调用函数的范围内,而在通过值传递时,修改不会出现在调用函数的范围内。”根据这个定义,任何C#“引用类型”都将是“通过引用传递”,而不是“通过值传递”。通过“通过值传递引用”在C++中,将使用一个指针,它指向C++开发人员,等于“通过引用”。它是在改变参数的值的情况下。对参数本身的改变(例如,代码> Builder = NeX-StudiBuilder()/代码>)对于调用方是不可见的。(例如,
builder.Append(“Foo”)
)将被看到,但这不会改变参数本身的值。参数的值只是一个引用,之后引用将是相同的。我真的不认为这里有任何争论-语言规范非常清楚。特别是,请参见C#4规范的第10.6.1.1节和第10.6.1.2节-“值参数”和“引用参数”。在“值参数”下:“允许方法将新值分配给值参数。此类分配仅影响值参数表示的本地存储位置;它们对方法调用中给出的实际参数没有影响。“这与参数的类型是引用类型还是值类型无关。也请阅读我关于该主题的文章:虽然更改参数的值相对不常见,但这绝非闻所未闻。例如,为了避免在方法的其余部分进行空性检查(但允许空引用作为输入)你可以用:
text=text???”;
开始一个方法。注意,这不是循环一个引用,而是循环一个变量(参数)。我想你回答的问题比OP提出的问题更高级。Eric提供了你建议的一般实现。@Brian:我很了解那篇文章;在过去几个月里,我曾几次偶然发现过它。但是,我对这篇文章的理解是OP希望传递一种重新计算属性的方法,而不是物业的当前价值;我的建议就是这样做的一种方式。谢谢,我肯定是误解了它的工作原理。文章很有帮助。