Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#基类的静态列表在实例化类型之间是否不同?_C#_Static Members - Fatal编程技术网

C#基类的静态列表在实例化类型之间是否不同?

C#基类的静态列表在实例化类型之间是否不同?,c#,static-members,C#,Static Members,我需要为我的对象创建唯一的ID,这些ID可以在应用程序实例之间保存和加载 我在当前的实现中实现了这一点,但这意味着我的每个类都需要几乎相同的代码,因此我决定在中创建一个基类,然后从中继承该代码。代码如下。我遇到的唯一问题是,因为基类中有一个静态列表,所以所有继承的类类型都被添加到同一个列表中 因此,如何更改代码,使列表“项”在不同类型之间是不同的列表 澄清。如果我有两门课,请列出: Foo:UniqueObject 条:唯一对象 我想让Foo和Bar拥有自己的静态项列表 抽象类UniqueObj

我需要为我的对象创建唯一的ID,这些ID可以在应用程序实例之间保存和加载

我在当前的实现中实现了这一点,但这意味着我的每个类都需要几乎相同的代码,因此我决定在中创建一个基类,然后从中继承该代码。代码如下。我遇到的唯一问题是,因为基类中有一个静态列表,所以所有继承的类类型都被添加到同一个列表中

因此,如何更改代码,使列表“项”在不同类型之间是不同的列表

澄清。如果我有两门课,请列出: Foo:UniqueObject 条:唯一对象 我想让Foo和Bar拥有自己的静态列表

抽象类UniqueObject
{
静态受保护的列表项=新列表();
静态随机rnd=新随机();
int-id;
public int Object_ID{get{return ID;}}
受保护的唯一对象()
{
id=generateUniqueID();
项目。添加(本);
}
受保护的唯一对象(int对象\u ID)
{
//确保传递的ID是唯一的
如果(!isIdUnique(对象ID))
{
//如果没有,则不会将其添加到项目列表中,并引发异常。
抛出新ArgumentNullException(“对象ID不唯一。已被另一个对象使用。”);
}
//如果我们到了这里,那么一定是独一无二的,所以添加它。
项目。添加(本);
}
/// 
///生成唯一标识符。
/// 
///唯一ID
私有int generateUniqueID()
{
//得到一个随机数
int val=rnd.Next();
//检查它是否唯一,如果没有,请获取另一个并重试。
而(!isIdUnique(val))
{
val=rnd.Next();
}
返回val;
}
/// 
///检查传递的ID是否与其他ID唯一
///“项目”列表中的对象。
/// 
///标识符。
/// 
私人住宅(国际ID)
{
foreach(项目中的唯一对象c)
{
如果(c.id==id)
返回false;
}
返回true;
}
}
我相信我可以使用泛型实现这一点,这样我就可以将类和列表更改为如下内容:

[TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void UniqueObjectTest()
        {
            var provider = new RemoteUniqueIdsProvider();

            var factory = new UniqueObjectsFactory<MyObjects>(provider);

            var entity = factory.GetNewEntity();
            var entity2 = factory.GetNewEntity();

            Assert.AreNotEqual(entity.UniqueId, entity2.UniqueId);


        }

    }
抽象类UniqueObject
{
静态受保护的列表项=新列表();
但这会给行项目带来其他错误。添加(此)


欢迎提供任何帮助。

如果您需要具有以下属性的唯一id:

1) 在当前应用程序域中是唯一的

2) 即使在处理应用程序的多个实例时,值也是唯一的

那么你需要考虑其中的一个解决方案:

1) 生成guid

2) 为您生成的ID创建一个唯一的“服务器”(可以为您的ID提供服务的公共服务器)

3) 如果您确切地知道有多少个应用程序实例,那么可以为每个实例定义一系列唯一的ID

最后,您需要将unicity的概念抽象为一个单独的服务,您可以在应用程序的任何层/层中移动。您的对象不能包含关于unicity的逻辑,这个概念是一个单独的关注点,您必须在其他组件中处理。请应用关注点分离模式

这就是我的实现(如果我是你)

公共接口IEntityWithUniqueId
{
void SetUniqueId(字符串uniqueId);
字符串唯一标识{get;}
}
公共接口IUniqueIdsProvider
{
字符串GetNewId();
}
公共类UniqueObject:IEntityWithUniqueId
{
公共字符串唯一ID{get;private set;}
void IEntityWithUniqueId.SetUniqueId(字符串uniqueId)
{
UniqueId=UniqueId;
}
}
公共类MyObject:唯一对象
{
}
公共类RemoteUniqueIdsProvider:IUniqueIdsProvider
{
公共字符串GetNewId()
{
//调用服务…,获取唯一ID
返回Guid.NewGuid().ToString().Replace(“-”,”);
}
}
公共类UniqueObjectsFactory,其中T:IEntityWithUniqueId,新()
{
私人iUniqueIDProvider(唯一供应商);
公共UniqueObjectsFactory(IUniqueIdsProvider uniqueIdsProvider)
{
_uniqueIdsProvider=uniqueIdsProvider;
}
公共T GetNewEntity()
{
var x=新的T();
x、 SetUniqueId(_uniqueIdsProvider.GetNewId());
返回x;
}
}
我写了一个这样的测试方法:

[TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void UniqueObjectTest()
        {
            var provider = new RemoteUniqueIdsProvider();

            var factory = new UniqueObjectsFactory<MyObjects>(provider);

            var entity = factory.GetNewEntity();
            var entity2 = factory.GetNewEntity();

            Assert.AreNotEqual(entity.UniqueId, entity2.UniqueId);


        }

    }
[TestClass]
公共类UnitTest1
{
[测试方法]
公共无效唯一对象测试()
{
var provider=新的RemoteUniqueIdsProvider();
var工厂=新的UniqueObjectsFactory(提供程序);
var entity=factory.GetNewEntity();
var entity2=factory.GetNewEntity();
Assert.AreNotEqual(entity.UniqueId,entity2.UniqueId);
}
}
要解释上述内容: 1) 接口IEntityWithUniqueId定义了应用程序中“唯一”对象的外观,因此它是一个具有UniqueId属性的对象,也是一个特殊方法:SetUniqueId。我没有使用get和set创建UniqueId属性,因为“set”将是一个基础结构操作,而get将是一个开发人员API

2) 接口IUniqueIdsProvider告诉您唯一Id提供程序的外观。它必须有一个简单的方法:GetNewId();为您提供唯一Id。实现可以在任何地方(服务器上、本地等)

3) UniqueObject类。该类是所有唯一对象的基类


4) UniqueObjectsFactory。这是为您提供新的唯一对象的类。从磁盘加载对象时,您必须从生成唯一ID的位置开始,这样在加载对象时您就不必再次检查唯一性了。

关于使用泛型的最后一句话,我想您可以这样做:

abstract class UniqueObject<T> where T : class

items.Add(this as T);

abstract class UniqueObject : IDisposable
{
   static protected HashSet<Guid> Guids = new HashSet<Guid>();
   Guid _id;

   public Guid ObjectID { get { return _id; } }

   protected UniqueObject()
   {
     do
     {
       _id = Guid.NewGuid();
     } while(Guids.Contains(_id));           
     Guids.Add(_id);
   }  

   protected UniqueObject(Guid guid)
   {
     if(Guids.Contains(guid))
       throw new ArgumentNullException("Object ID is not unique. Already being used by another object.");
     _id = guid;
   }

   // Make a better implementation of IDisposable
   public void Dispose()
   {
     guids.Remove(_id);
   }
}
// static members
static protected Random rnd = new Random();
static protected HashSet<int> ids = new HashSet<int>();
// ... in the constructor:
do
{
  _id = rnd.Next();
} while(ids.Contains(_id));