- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现一个继承自泛型 List<T>
的类类(class):
Class MyList::List<MyClass>
List<T>::Item[Int32]
indexer 属性在我的一种方法中,但我不知道该怎么做。
List<MyClass>::[i]
和
List<MyClass>::Item[i]
,但两者都不起作用。
List<MyClass>
调用其他方法,例如
Add
,我可以做
List<MyClass>::Add(myInstance)
.
最佳答案
从 List<T>.Item[Int32]
是一个默认的索引器,你可以做 this[i]
.例如:
public ref class MyList : System::Collections::Generic::List<MyClass ^>
{
public:
int CountNonNull();
};
int MyList::CountNonNull()
{
int nonNull = 0;
for (int i = 0; i < Count; i++)
{
if (this[i] != nullptr)
nonNull++;
}
return nonNull;
}
default[i]
明确:
if (this->default[i] != nullptr)
nonNull++;
List<MyClass ^>::default[i]
也是有效的,可用于在覆盖索引器本身时调用基本索引器。
List<T>.Item[Int32]
默认索引器:
I intend to implement a class that stores a list of images. Depending on some conditions, my indexer would either return the raw image or a processed image.
List<T>
继承因为
List<T>.Item[Int32]
是
非虚拟 并且不打算被覆盖。因此,您只能通过
interface re-implementation 隐藏它。 .但这会使您的应用程序面临一个可能的错误:如果您的
MyList
永远向上转换为基类
List<MyClass ^>
,则不会调用替换索引器。更糟糕的是,似乎
List<T>.GetEnumerator()
返回的枚举数不会调用您的替换索引器,因此只需遍历
MyList
将导致退回未处理的元素。
ref class MyList;
public ref class MyClass
{
public:
property bool Processed;
};
public ref class MyList : List<MyClass ^>, IList<MyClass ^>
{
public:
// default indexer
virtual property MyClass^ default[int]
{
MyClass^ get(int index) new = IList<MyClass ^>::default::get // hiding + interface reimplementation of default::get method
{
MyClass^ item = List<MyClass ^>::default[index]; // Call base default indexer
item = ProcessItem(item); // Add your custom logic here
return item; // return the item
}
void set(int index, MyClass^ value) new = IList<MyClass ^>::default::set // hiding + interface reimplementation of default::set method
{
List<MyClass ^>::default[index] = value; // Call base default indexer
}
}
private:
MyClass^ ProcessItem(MyClass ^item)
{
// Add your custom logic here
if (item != nullptr)
item->Processed = true;
return item;
}
};
get
方法调用
ProcessItem()
在退回之前进行处理。 (您的图像处理将在此处进行;在示例中,
bool
设置为
true
。)
MyList ^list = gcnew MyList();
list->Add(gcnew MyClass());
for each (MyClass^ item in list)
Debug::Assert(item->Processed); // FAILS because enumerator doesn't call indexer!
list->Add(gcnew MyClass());
Debug::Assert(list[list->Count-1]->Processed); // Passes because re-implemented Add() was called.
// Upcast to base class
List<MyClass ^>^ baseList = list;
baseList->Add(gcnew MyClass());
Debug::Assert(baseList[list->Count-1]->Processed); // FAILS because re-implemented Add() was NOT called!
// Upcast to interface
IList<MyClass ^>^ iList = list;
iList->Add(gcnew MyClass());
Debug::Assert(iList[iList->Count-1]->Processed); // Passes because re-implemented Add() was called.
get()
方法没有被调用。这真的是无法避免的;通过
new
重新实现接口(interface)关键字实际上并没有覆盖基本实现,它在 vtable 中创建一个带有新插槽的新实现。见:
new (new slot in vtable) (C++/CLI and C++/CX) .
System.Collections.ObjectModel.Collection<T>
继承它提供了 protected 虚拟方法,每当从集合中添加或删除项目时都会调用这些方法。 (这是
ObservableCollection<T>
的基类。)
MyList
如下:
public ref class MyList : Collection<MyClass ^>
{
protected:
virtual void InsertItem(int index, MyClass ^ item) override
{
Collection<MyClass ^>::InsertItem(index, ProcessItem(item));
}
virtual void SetItem(int index, MyClass ^ item) override
{
Collection<MyClass ^>::InsertItem(index, ProcessItem(item));
}
private:
MyClass^ ProcessItem(MyClass ^item)
{
// Add your custom logic here
if (item != nullptr)
item->Processed = true;
return item;
}
};
MyList ^list = gcnew MyList();
list->Add(gcnew MyClass());
for each (MyClass^ item in list)
Debug::Assert(item->Processed); // Passes
list->Add(gcnew MyClass());
Debug::Assert(list[list->Count-1]->Processed); // Passes
// Upcast to base class
Collection<MyClass ^>^ baseList = list;
baseList->Add(gcnew MyClass());
Debug::Assert(baseList[list->Count-1]->Processed); // Passes
// Upcast to interface
IList<MyClass ^>^ iList = list;
iList->Add(gcnew MyClass());
Debug::Assert(iList[iList->Count-1]->Processed); // Passes
get()
方法,您可以使用
decorator pattern并创建自己的自定义集合实现
List<MyClass ^
> 包装底层
List<MyClass ^>
并在其自己的默认索引器、枚举器
CopyTo()
中进行必要的处理以及根据需要访问项目的其他方法:
public ref class MyList : IList<MyClass ^>
{
private:
List<MyClass ^> list;
public:
MyList()
{
list = gcnew List<MyClass ^>();
}
virtual property MyClass^ default[int]
{
MyClass^ get(int index)
{
MyClass^ item = list[int];
item = ProcessItem(item); // Add your custom logic here
return item;
}
void set(int index, MyClass^ value)
{
list[index] = value;
}
}
// Implement all other methods as required.
virtual property int Count { int get() { return list->Count; } }
// Etc
};
关于c++-cli - 如何在 c++/cli 中调用基类索引器属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59365870/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!