正在确定基类中的泛型类型



我有以下类。AuthorTestBookTest都继承自MyBaseClass,后者有一个接受泛型参数的方法AddName

public class Book {
public string Name {get;set;}
}
public class Author {
public string FirstName {get;set;}
public string LastName {get;set;}
}
public class BookTest : MyBaseClass {
Book book = // book object
base.AddName<Book>(book);
}
public class AuthorTest : MyBaseClass {
Author author = // author object
base.AddName<Author>(author);
}
public interface IMyBaseClass {
void AddName<T>(T item);
}
public class MyBaseClass : IMyBaseClass {
public void AddName<T>(T item) {
// item could either be Book or Name
var name = item.Name
// or
var name = item.FirstName + " " item.LastName;
}
}

在基类中,如何确定传入哪种类型的T(Book或Author(?在此基础上,我需要构造name变量。有没有一种优雅的方法可以做到这一点?

虽然您的层次结构和泛型的使用似乎都非常可疑,但问题的简单答案是,您执行运行时类型测试,就像对泛型类型参数执行测试一样,就像对其他值执行测试一样

public class MyBaseClass : IMyBaseClass
{
public void AddName<T>(T item)
{
// item could either be Book or Author
var name = item switch
{
Author a => $"{a.FirstName} {a.LastName}",
Book b => b.Name,
_ => throw new ArgumentException(nameof(item), $"Invalid type: {a?.GetType()}")
};
}
}

然而,正如其他人已经指出的那样,由于您只支持一组固定的类型,重载将更合适。

public class MyBaseClass : IMyBaseClass
{
public void AddName(Author author)
{
var name = $"{author.FirstName} {author.LastName}";
}
public void AddName(Book book) {
var name = book.Name;
}
}

我觉得最好将泛型类型参数从方法移动到类型本身。如果您正在编写一个BookTest,并且测试与Book相关联,那么更自然的做法是这样定义您的类型:class BookTest : MyBaseClass<Book>

下面是基类:

public interface IMyBaseClass<T>
{
void AddName(T item);
}
public abstract class MyBaseClass<T> : IMyBaseClass<T>
{
protected abstract string GetName(T item);

public void AddName(T item)
{
var name = this.GetName(item);
}
}

然后你这样写你的测试:

public class BookTest : MyBaseClass<Book>
{
protected override string GetName(Book item)
{
return item.Name;
}
}
public class AuthorTest : MyBaseClass<Author>
{
protected override string GetName(Author item)
{
return $"{item.FirstName} {item.LastName}";
}
}

它都是强类型的,每个类都有明确的责任。

最新更新