您如何看待以下代码?这个好吗?如果是这样,为什么呢?如果不是,为什么不呢? CLR如何看到这段代码?
public abstract class EntityBase<TEntity> : IEquatable<TEntity>
{
public bool Equals(TEntity other)
{
// check equalitiy
}
// yes, below is object's Equals and GetHashCode method implementation
}
public class Person : EntityBase<Person>
{
}
我对此有点奇怪的感觉。喜欢鸡肉和鸡蛋的问题。这里是.Net框架代码,具有相同的行为。
public sealed class String : IComparable<string>, IEquatable<string> // I removed other interfaces
有什么想法吗?
答案 0 :(得分:2)
在适当的情况下(例如实施IComparable<T>
),这是正确的做法。
但这只能根据具体情况确定,并详细考虑其原因。
另一方面,C ++允许“奇怪的重复基础模式”:
template<typename T>
class SomeWrapper<T> : T { ... ]
其中泛型类继承其通用包装器。这允许一些高级包装方案,但如果在包装之外使用,可能会快速变得混乱。幸运的是(?).NET中不允许使用这种模式。
答案 1 :(得分:1)
不是一个真正的答案,但在我写完这个奇怪的代码后,我发现它有点意义......
class Program
{
static void Main(string[] args)
{
var wife = new Human(Gender.Female);
var baby = wife.GiveBirth();
Console.WriteLine(baby.Gender);
Console.ReadKey();
}
}
class CanGiveBirthTo<T> where T : new()
{
public CanGiveBirthTo()
{
}
public T GiveBirth()
{
return new T();
}
}
class Human : CanGiveBirthTo<Human>
{
public Gender Gender { get; private set; }
public Human(Gender gender)
{
Gender = gender;
}
public Human()
{
Gender = RandomlyAssignAGender();
}
Gender RandomlyAssignAGender()
{
var rand = new Random();
return (Gender) rand.Next(2);
}
}
enum Gender
{
Male = 0,
Female = 1
}
答案 2 :(得分:0)
我发现您的代码没有问题。为什么会出问题呢?
关于内部表示,dotNet JIT为每个通用版本编译一个类。以下是:
class Foo<T> { public T Property; }
Foo<Int> fooint;
Foo<String> foostring;
有点编译成:
class FooInt { public Int Property; }
class FooString { public String Property; }
FooInt fooint;
FooString foostring;
// This is kept for if it is needed later.
// For example for generic casting, a C#4 feature.
class Foo<T> { public T Property; }
答案 3 :(得分:0)
对于其他人的参考,我复制了Eric Lippert的答案(在评论中回答)。
虽然出现了定义 循环,它不是。但是,C# 编译器循环检测算法是 既错又弱。错了,因为它 错误地将非循环检测为 循环,因为它没有失败 检测某些非常讨厌的周期。如果 这个话题让你感兴趣,看看我的 文章在这里: http://blogs.msdn.com/ericlippert/archive/2008/05/07/covariance-and-contravariance-part-twelve-to-infinity-but-not-beyond.aspx