gpt4 book ai didi

c# - 是否可以在传递给基础构造函数之前进行转换?

转载 作者:行者123 更新时间:2023-11-30 14:58:29 25 4
gpt4 key购买 nike

我正在尝试创建一个抽象的通用管理器,它将提供添加/删除的事件,并提供用于创建和完成项目的抽象方法。

下面是我想出的代码,但是在 TestClass 构造函数中,将 TestManager 的 ManagerBase 参数传递给 base 会产生无效转换的编译器错误,即使 TestManager 肯定是 ManagerBase。

可以使 Manager 字段成为“对象”并在运行时进行转换,但这会很丑陋。

是否有可能让它发挥作用,或者我走错了方向?

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace ManagerTest
{
class Program
{
static void Main(string[] args)
{
var Manager = new TestManager();
Manager.ItemAdded += (manager, item) => Debug.WriteLine("Item added: " + item.Id);
Manager.ItemRemoved += (manager, item) => Debug.WriteLine("Item removed: " + item.Id);

var entity1 = Manager.Create("entity1");
var entity2 = Manager.Create("entity2");
Manager.Remove("entity1");
var entity3 = Manager.Create("entity3");
Manager.Remove("entity3");
Manager.Remove("entity4");
}
}

class TestClass : EntityBase, IDisposable
{
public TestClass(string id, TestManager manager) : base(id, manager) { Debug.WriteLine(Id + " - ctor"); }
public void Dispose() { Debug.WriteLine(Id + " - disposed"); }
}

class TestManager : ManagerBase<TestClass>
{
protected override TestClass CreateInternal(string key) { return new TestClass(key, this); }
protected override void FinalizeRemove(TestClass item) { item.Dispose(); }
}

abstract class EntityBase
{
public string Id { get; private set; }
public ManagerBase<EntityBase> Manager { get; private set; }

public EntityBase(string id, ManagerBase<EntityBase> manager)
{
this.Id = id;
this.Manager = manager;
}
}

abstract class ManagerBase<T> where T : EntityBase
{
public event Action<ManagerBase<T>, T> ItemAdded;
public event Action<ManagerBase<T>, T> ItemRemoved;

private readonly Dictionary<string, T> Storage = new Dictionary<string, T>();

protected abstract T CreateInternal(string key);
protected abstract void FinalizeRemove(T item);

public T Create(string key)
{
T newItem = null;

lock (Storage)
{
if (!Storage.ContainsKey(key))
{
newItem = CreateInternal(key);

Storage.Add(key, newItem);

ItemAdded.SafeInvoke(this, newItem);
}
}

return newItem;
}

public T Get(string key)
{
lock (Storage)
return Storage.ContainsKey(key) ? Storage[key] : null;
}

public bool Contains(string key)
{
lock (Storage)
return Storage.ContainsKey(key);
}

public bool Remove(string key)
{
bool returnValue = false;

lock (Storage)
if (Storage.ContainsKey(key))
{
var item = Storage[key];
returnValue = Storage.Remove(key);
ItemRemoved.SafeInvoke(this, item);
FinalizeRemove(item);
}

return returnValue;
}
}

static class Extensions
{
public static void SafeInvoke<T1, T2>(this Action<T1, T2> action, T1 arg1, T2 arg2)
{
var actionCopy = action;
if (actionCopy != null)
actionCopy(arg1, arg2);
}
}
}

最佳答案

修改后的代码

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace ManagerTest
{
class Program
{
static void Main(string[] args)
{
var Manager = new TestManager();
Manager.ItemAdded += (manager, item) => Debug.WriteLine("Item added: " + item.Id);
Manager.ItemRemoved += (manager, item) => Debug.WriteLine("Item removed: " + item.Id);

var entity1 = Manager.Create("entity1");
var entity2 = Manager.Create("entity2");
Manager.Remove("entity1");
var entity3 = Manager.Create("entity3");
Manager.Remove("entity3");
Manager.Remove("entity4");
}
}

class TestClass : EntityBase, IDisposable
{
public TestClass(string id, TestManager manager) : base(id, manager) { Debug.WriteLine(Id + " - ctor"); }
public void Dispose() { Debug.WriteLine(Id + " - disposed"); }
}

class TestManager : ManagerBase<TestClass>, IManagerBase<TestClass>
{
protected override TestClass CreateInternal(string key) { return new TestClass(key, this); }
protected override void FinalizeRemove(TestClass item) { item.Dispose(); }
}

abstract class EntityBase
{
public string Id { get; private set; }
public IManagerBase<EntityBase> Manager { get; private set; }

public EntityBase(string id, IManagerBase<EntityBase> manager)
{
this.Id = id;
this.Manager = manager;
}
}

interface IManagerBase<out T>
where T : EntityBase
{
event Action<IManagerBase<T>, T> ItemAdded;
event Action<IManagerBase<T>, T> ItemRemoved;
T Create(string key);
T Get(string key);
bool Contains(string key);
bool Remove(string key);
}

abstract class ManagerBase<T> : IManagerBase<T> where T : EntityBase
{
public event Action<IManagerBase<T>, T> ItemAdded;
public event Action<IManagerBase<T>, T> ItemRemoved;

private readonly Dictionary<string, T> Storage = new Dictionary<string, T>();

protected abstract T CreateInternal(string key);
protected abstract void FinalizeRemove(T item);

public T Create(string key)
{
T newItem = null;

lock (Storage)
{
if (!Storage.ContainsKey(key))
{
Storage.Add(key, CreateInternal(key));

ItemAdded.SafeInvoke(this, newItem);
}
}

return newItem;
}

public T Get(string key)
{
lock (Storage)
return Storage.ContainsKey(key) ? Storage[key] : null;
}

public bool Contains(string key)
{
lock (Storage)
return Storage.ContainsKey(key);
}

public bool Remove(string key)
{
bool returnValue = false;

lock (Storage)
if (Storage.ContainsKey(key))
{
var item = Storage[key];
returnValue = Storage.Remove(key);
ItemRemoved.SafeInvoke(this, item);
FinalizeRemove(item);
}

return returnValue;
}
}

static class Extensions
{
public static void SafeInvoke<T1, T2>(this Action<T1, T2> action, T1 arg1, T2 arg2)
{
var actionCopy = action;
if (actionCopy != null)
actionCopy(arg1, arg2);
}
}
}

关于c# - 是否可以在传递给基础构造函数之前进行转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18905166/

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