C# 对泛型类中的类型执行特殊处理
19分钟前对泛型类Pinnew成员dan neely中的类型执行特殊处理 我正在尝试将一些旧的(最初是.NET1.1)抽象类汇总到泛型中。这些类都为特定类型的数据对象提供了类似的功能。在大多数情况下,事情进展顺利,但我遇到过一些地方,其中一个数据对象的类型需要在一个方法中进行额外的处理,而不是所有其他类型所需要的处理。我可以检查T的类型,看看它是否是我需要进行特殊处理的类型,但是从T到SpecialType的转换不会编译。我有没有别的方法可以做到这一点,或者我想做的事情是不可能的C# 对泛型类中的类型执行特殊处理,c#,generics,casting,C#,Generics,Casting,19分钟前对泛型类Pinnew成员dan neely中的类型执行特殊处理 我正在尝试将一些旧的(最初是.NET1.1)抽象类汇总到泛型中。这些类都为特定类型的数据对象提供了类似的功能。在大多数情况下,事情进展顺利,但我遇到过一些地方,其中一个数据对象的类型需要在一个方法中进行额外的处理,而不是所有其他类型所需要的处理。我可以检查T的类型,看看它是否是我需要进行特殊处理的类型,但是从T到SpecialType的转换不会编译。我有没有别的方法可以做到这一点,或者我想做的事情是不可能的 class M
class MyGenericClass : ICloneable where T: class, new()
{
private T m_storedClass;
...
private DoStuff()
{
//do stuff for all types
//objects of SpecialType need extra stuff done.
if (typeof(T) == typeof(SpecialType))
{
//compiler error: Error Cannot convert type 'T' to 'SpecialType'
((SpecialType)m_storedClass).SpecialString = "foo";
}
}
除非你这样做,否则这是行不通的
class MyGenericClass : ICloneable
where T: class, new(), SpecialType
还是这个
class MyGenericClass : ICloneable
where T: class, new(), BaseTypeOfSpecialType
或者可能是这样:
class MyGenericClass : ICloneable
where T: class, new(), InterfaceOnSpecialType
也许你不需要这样做——如果你发布了一个更完整的问题,也许我可以帮助你找到一种方法来避免这样做。除非你这样做,否则这不会起作用
class MyGenericClass : ICloneable
where T: class, new(), SpecialType
还是这个
class MyGenericClass : ICloneable
where T: class, new(), BaseTypeOfSpecialType
或者可能是这样:
class MyGenericClass : ICloneable
where T: class, new(), InterfaceOnSpecialType
也许你不需要这样做——如果你发布了一个更完整的问题,也许我可以帮助你找到一种方法来避免这样做。这样的事情怎么样:
interface ISomething
{
void DoSomething();
}
class NormalType : ISomething
{
// ...
public void DoSomething() { /* nothing to do */ }
}
class SpecialType : ISomething
{
// ...
public void DoSomething() { this.SpecialString = "foo" }
}
class MyGenericClass : ICloneable
{
private ISomething m_storedClass;
private DoStuff()
{
// ...
m_storedClass.DoSomething();
}
}
像这样的怎么样:
interface ISomething
{
void DoSomething();
}
class NormalType : ISomething
{
// ...
public void DoSomething() { /* nothing to do */ }
}
class SpecialType : ISomething
{
// ...
public void DoSomething() { this.SpecialString = "foo" }
}
class MyGenericClass : ICloneable
{
private ISomething m_storedClass;
private DoStuff()
{
// ...
m_storedClass.DoSomething();
}
}
您可以通过使用约束使其工作,但这段代码有一种奇怪的味道
有没有其他方法可以在不破坏类的“通用性”的情况下获得额外的处理?您可以通过使用约束使其工作,但这段代码有一种奇怪的味道 有没有其他方法可以在不破坏类的“通用性”的情况下获得额外的处理呢?它在C#中不起作用,编译器不允许您这样做。。。如果您不能接受其他人建议的接口/基类约束,我有一个不太好但可行的解决方案: 您尝试执行的强制转换在C++/CLI中工作。你必须自己决定它是否值得。它在C#中不起作用,编译器不会让你这么做。。。如果您不能接受其他人建议的接口/基类约束,我有一个不太好但可行的解决方案:
您尝试执行的强制转换在C++/CLI中工作。你必须自己决定它是否值得。下面的编译很好
if (typeof(T) == typeof(SpecialClass))
{
(this.m_storedClass as SpecialClass).SpecialOperation();
}
首先强制转换到对象
是另一种解决方案
if (typeof(T) == typeof(SpecialClass))
{
((SpecialClass)((Object)this.m_storedClass)).SpecialOperation();
}
请注意,支票也可以改写为以下内容
if (this.m_storedClass is SpecialClass)
{
(this.m_storedClass as SpecialClass).SpecialOperation();
}
或者只使用单个as
运算符,在条件中免费包含非空检查
SpecialClass special = this.m_storedClass as SpecialClass;
if (special != null)
{
special.SpecialOperation();
}
下面的代码编译得很好
if (typeof(T) == typeof(SpecialClass))
{
(this.m_storedClass as SpecialClass).SpecialOperation();
}
首先强制转换到对象
是另一种解决方案
if (typeof(T) == typeof(SpecialClass))
{
((SpecialClass)((Object)this.m_storedClass)).SpecialOperation();
}
请注意,支票也可以改写为以下内容
if (this.m_storedClass is SpecialClass)
{
(this.m_storedClass as SpecialClass).SpecialOperation();
}
或者只使用单个as
运算符,在条件中免费包含非空检查
SpecialClass special = this.m_storedClass as SpecialClass;
if (special != null)
{
special.SpecialOperation();
}
同意。这里有一点代码的味道,但如果不了解更多关于确切代码的信息,很难判断什么是好的重构。你们中的一些人注意到的味道是,必须为第三方应用程序输出数据,而第三方应用程序的文件格式不允许存储我的应用程序所需的所有数据。在这种情况下,SpecialType需要跟踪是否创建了第三方文件。我根据第二个文件的存在来设置该值,而不是将其作为标志存储在我的文件中,以避免状态被破坏的风险(例如有人通过资源管理器删除第三方文件),以进一步澄清。MyGenericClass还管理不需要任何第三方hoop jumping的其他数据文件格式。同意。这里有一点代码的味道,但如果不了解更多关于确切代码的信息,很难判断什么是好的重构。你们中的一些人注意到的味道是,必须为第三方应用程序输出数据,而第三方应用程序的文件格式不允许存储我的应用程序所需的所有数据。在这种情况下,SpecialType需要跟踪是否创建了第三方文件。我根据第二个文件的存在来设置该值,而不是将其作为标志存储在我的文件中,以避免状态被破坏的风险(例如有人通过资源管理器删除第三方文件),以进一步澄清。MyGenericClass还管理其他不需要任何第三方支持的数据文件格式。+1-更好。如果您不能修改存储类,另一种方法是专门研究t和TSomething。在必须维护实现接口的单独类的情况下,我是否真的比遗留抽象/继承类方法有所收获?请忽略我之前的评论。我误解了您的示例,认为我将接口作为MYGenericClass的一部分,而不是它所包含的对象。在MYGenericClass的约束中使用接口而不是类会使我无法为null。有没有办法读取约束?类MyGenericClass:iClonable,其中T:IMyInterface,new()+1-更好。如果您不能修改存储类,另一种方法是专门研究t和TSomething。在必须维护实现接口的单独类的情况下,我是否真的比遗留抽象/继承类方法有所收获?请忽略我之前的评论。我误解了您的示例,认为我将接口作为MYGenericClass的一部分,而不是它所包含的对象。在MYGenericClass的约束中使用接口而不是类会使我无法为null。有没有办法读取约束?类MyGenericClass:iClonable where T:IMyInterface,new(),即使没有Daniel Brückner的C#options C++/CLI,也会有巨大的杀伤力。同意,我认为这在C#中是不可能的,但学习新东西很好,即使没有Daniel Brückner的C#options C++/CLI也会有巨大的杀伤力。同意,我认为这在C#中是不可能的,但学习新东西很好