我经常通过向它添加自引用("反身")类型参数约束来使一个简单的界面变得更加复杂.例如,我可能会这样:
interface ICloneable
{
ICloneable Clone();
}
class Sheep : ICloneable
{
ICloneable Clone() { … }
} //^^^^^^^^^^
Sheep dolly = new Sheep().Clone() as Sheep;
//^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
成:
interface ICloneable<TImpl> where TImpl : ICloneable<TImpl>
{
TImpl Clone();
}
class Sheep : ICloneable<Sheep>
{
Sheep Clone() { … }
} //^^^^^
Sheep dolly = new Sheep().Clone();
Run Code Online (Sandbox Code Playgroud)
主要优点:实现类型(例如Sheep)现在可以引用自身而不是其基类型,从而减少了对类型转换的需求(如最后一行代码所示).
虽然这非常好,但我也注意到这些类型参数约束并不直观,并且在更复杂的场景中变得非常难以理解.*)
问题:有没有人知道另一种C#代码模式可以实现相同的效果或类似的东西,但是更容易掌握?
*)此代码模式可能不直观且难以理解,例如以下方式:
声明
X<T> where T : X<T>似乎是递归的,人们可能想知道为什么编译器不会陷入无限循环,推理,"如果T是X<T>,那么X<T>实际上是一个 …
我有一个带有递归parent_id的自引用MySQL表:
CREATE TABLE `recursive` (
`id` int(11) NOT NULL auto_increment,
`parent_id` int(11) default NULL,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `data_categorysource_parent_id` (`parent_id`),
CONSTRAINT `parent_id_refs_id_627b4293`
FOREIGN KEY (`parent_id`) REFERENCES `data_categorysource` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
在测试期间,我想清空它但TRUNCATE失败:
TRUNCATE `recursive`
/* SQL Error: Cannot delete or update a parent row: a foreign key
constraint fails...
Run Code Online (Sandbox Code Playgroud)
我目前必须手动删除所有记录,从树的底部开始向上工作.即使是小树也会变得繁重.
有一个简单的方法吗?我不能DROP在表中重新创建它,因为其他表引用它(我已经截断了那些,所以那里应该没有数据完整性问题).
我有一个用户可以收集他喜欢的用户...
另一个用户可以收集他喜欢的用户....
如果用户A喜欢用户B,并且用户B喜欢用户A,那么他们就会挂出.我需要向对方发送他们的联系信息.我们如何在Entity Framework Code First中代表这样的模型?
public class User
{
public int UserId { get; set; }
public int? UserLikeId { get; set; }
public virtual UserLike UserLike { get; set; }
}
public class UserLike
{
public int UserLikeId { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public virtual ICollection<User> LikeUsers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这个型号是否正确?我不能让这个工作.
我尝试过另一种方式,但这也不行...
我试图将用户集合添加到用户表.
例如:
public virtual ICollection<User> userlike { get; set; } …Run Code Online (Sandbox Code Playgroud) entity-framework self-join self-reference ef-code-first entity-framework-4.1
尝试在其内部引用一个类。例如
class Test:
FOO_DICT = {1 : Test.bar} # NameError: name 'Test' is not defined
@staticmethod
def bar():
pass
Run Code Online (Sandbox Code Playgroud)
这种用法有意义吗?还有更好的选择吗?谢谢!
我有这个简单的界面:
public interface Node<E extends Node<E>>
{
public E getParent();
public List<E> getChildren();
default List<E> listNodes()
{
List<E> result = new ArrayList<>();
// ------> is this always safe? <-----
@SuppressWarnings("unchecked")
E root = (E) this;
Queue<E> queue = new ArrayDeque<>();
queue.add(root);
while(!queue.isEmpty())
{
E node = queue.remove();
result.add(node);
queue.addAll(node.getChildren());
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
我看到它this总是Node<E>(根据定义)的一个实例.
但是我无法想象一个this不是实例的情况E......
因为E extends Node<E>,不应该也不Node<E>等同于E定义?
你能给出一个实例的对象的例子Node<E>,但它不是一个实例E吗?
与此同时,我的大脑正在融化......
上一课是一个简化的例子. …
对于TypeScript 1.7中的Polymorphic,我在这里发现,我们可以在类中定义一个返回类型为的方法this,并自动地,任何扩展该类并继承方法的类,将其返回类型设置为各自的this类型.像这样:
class Model {
save():this { // return type: Model
// save the current instance and return it
}
}
class SomeModel extends Model {
// inherits the save() method - return type: SomeModel
}
Run Code Online (Sandbox Code Playgroud)
但是,我所追求的是拥有一个static带有返回类型的继承方法,引用类本身.最好用代码描述:
class Model {
static getAll():Model[] {
// return all recorded instances of Model as an array
}
save():this {
// save the current instance and return it
}
}
class SomeModel extends Model …Run Code Online (Sandbox Code Playgroud) 在多年前在一个论坛中看到一个从未解决过的对话之后,它让我想知道如何正确地创建一个引用自身的元组.从技术上讲,这是一个非常糟糕的主意,因为元组应该是不可变的.一个不可变对象怎么可能包含自己呢?但是,这个问题不是关于最佳实践,而是关于Python中可能的内容的查询.
import ctypes
def self_reference(array, index):
if not isinstance(array, tuple):
raise TypeError('array must be a tuple')
if not isinstance(index, int):
raise TypeError('index must be an int')
if not 0 <= index < len(array):
raise ValueError('index is out of range')
address = id(array)
obj_refcnt = ctypes.cast(address, ctypes.POINTER(ctypes.c_ssize_t))
obj_refcnt.contents.value += 1
if ctypes.cdll.python32.PyTuple_SetItem(ctypes.py_object(array),
ctypes.c_ssize_t(index),
ctypes.py_object(array)):
raise RuntimeError('PyTuple_SetItem signaled an error')
Run Code Online (Sandbox Code Playgroud)
前一个函数旨在访问Python的C API,同时牢记内部结构和数据类型.但是,运行该函数时通常会生成以下错误.通过未知的过程,之前可以通过类似的技术创建自引用元组.
问题:如何self_reference修改功能以始终如一地工作?
>>> import string
>>> a = tuple(string.ascii_lowercase)
>>> self_reference(a, 2)
Traceback (most recent call last):
File …Run Code Online (Sandbox Code Playgroud) 我只是想确保我做得对,这不会造成任何疑虑.
我有一个自称的功能,如果可以或不这样做需要你的批准?
<?php
function determine($the_array){
foreach ($the_array as $key => $value) {
switch ($key) {
case 'in':
echo $value;
break;
case 'out':
echo $value;
break;
case 'level':
echo '<ul>';
determine($value);
echo '</ul>';
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是数组:
$the_array = array(
'in' => '<li>Simple IN</li>',
'out' => '<li>Simple OUT</li>',
'level' => array(
'in' => '<li>Simple IN 2</li>',
'out' => '<li>Simple OUT 2</li>',
'level' => array(
'in' => '<li>Simple IN 3</li>',
'out' => '<li>Simple OUT 3</li>'
),
),
);
Run Code Online (Sandbox Code Playgroud)
这是最终的初始化:
echo '<ul>'; …Run Code Online (Sandbox Code Playgroud) Python的print声明通常似乎打印repr()其输入.元组似乎不是例外:
>>> print (1, 2, 3)
(1, 2, 3)
>>> print repr((1, 2, 3))
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
但是当我弄乱CPython的内部时,我偶然发现了一些奇怪的行为.简而言之:如果您使用Python 2来创建自引用元组,则直接打印它的行为与打印其repr()/ str()/ unicode()表示完全不同.
>>> print outer # refer to the link above
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
... many lines later ...
((((((((((Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError: stack overflow
>>> print repr(outer)
((...),)
>>> print str(outer)
((...),)
>>> print unicode(outer)
((...),)
Run Code Online (Sandbox Code Playgroud)
到底是print做什么的?为了尝试自己回答这个问题,我提到了语言参考:
6.6.该
print …
我一直在阅读Albaharis的"C#5.0 in A Nutshell",我在Generics部分遇到过这个问题,据说这是合法的:
class Bar<T> where T : Bar<T> { ... }
Run Code Online (Sandbox Code Playgroud)
尽管我仔细阅读了整章,但这对我来说毫无意义.我甚至无法理解它.
有人可以用一些可以理解的命名来解释它,例如:
class Person<T> where T : Person<T> { ... }
Run Code Online (Sandbox Code Playgroud)
还有一个真实的应用场景,这种用法是否合适且有用?