gpt4 book ai didi

c# - 分配免费委托(delegate)或其他方式通过地址调用方法?

转载 作者:可可西里 更新时间:2023-11-01 08:46:15 24 4
gpt4 key购买 nike

我需要能够使用 Mono 在 C# 中基于函数指针调用单个方法。委托(delegate)为此工作得很好,这是他们的目的,但每次我设置委托(delegate)时他们似乎都分配 52 个字节(不是 +=,而是使用 = 设置它,所以委托(delegate)总是引用一个且只有一个方法)。

这个委托(delegate)每秒更改很多次,它会导致 GC 周期性地启动,我希望避免这种情况。

我不介意初始内存分配,但有没有办法在我每次更改单个委托(delegate)值时阻止分配?

如果不是,除了每次地址更改时不会分配任何内存的委托(delegate)之外,是否还有其他动态方式在 C# 中调用方法?

最佳答案

任何你这样写的代码

Action action = foo.DoSomething;

最终被编译成这个

Action action = new Action(foo.DoSomething);

这是分配的来源。没有任何完美的方法可以解决这个问题,但要防止分配,您需要缓存和重用委托(delegate)。

实现端修复

您可以通过为每个方法创建一个委托(delegate)来在实现方面实现这一点。

public class Foo
{
public void DoSomething() { /*nop*/ }

private Action _doSomethingDelegate;
public Action DoSomethingDelegate
{
get { return _doSomethingDelegate ?? (_doSomethingDelegate = DoSomething); }
}
}

然后你将只引用现有的委托(delegate)而不是方法

Action action = foo.DoSomethingDelegate;

缓存修复

另一种选择是使用某种缓存类,但这会引入一大堆对象生命周期问题,您可能不希望这些问题出现在游戏场景中。这是一个有点粗略的实现,真实的人可能想使用弱引用。

public static class DelegateCache
{
private static readonly Dictionary<object, Dictionary<string, Delegate>> Cache = new Dictionary<object, Dictionary<string, Delegate>>();

private static Dictionary<string, Delegate> GetObjectCache(object instance)
{
Dictionary<string, Delegate> delegates;
if (!Cache.TryGetValue(instance, out delegates))
{
Cache[instance] = delegates = new Dictionary<string, Delegate>();
}
return delegates;
}

public static T GetDelegate<T>(object instance, string method)
where T: class
{
var delegates = GetObjectCache(instance);
Delegate del;
if (!delegates.TryGetValue(method, out del))
{
delegates[method] = del = Delegate.CreateDelegate(typeof(T), instance, method);
}
return del as T;
}
}

使用它看起来像这样

Action action = DelegateCache.GetDelegate<Action>(foo, "DoSomething");

总结

运行一些测试,这两种方法对每个对象/方法对只有一个分配。我可能会去实现方面修复它,即使它需要做很多工作,它也会更干净。如果有很多方法并且您计划添加更多方法,则可以使用 T4 为您的方法生成一个带有委托(delegate)实现的分部类。

关于c# - 分配免费委托(delegate)或其他方式通过地址调用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20837187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com