Program Tip

클래스를 사용하는 모든 파일에 한 줄의 코드를 추가하지 않고 C #에서 클래스 이름에 별칭을 지정하려면 어떻게해야합니까?

programtip 2020. 10. 28. 20:35
반응형

클래스를 사용하는 모든 파일에 한 줄의 코드를 추가하지 않고 C #에서 클래스 이름에 별칭을 지정하려면 어떻게해야합니까?


클래스 이름에 대한 별칭을 만들고 싶습니다. 다음 구문은 완벽합니다.

public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
   ...
}

public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;

그러나 컴파일되지 않습니다.


참고이 예제는 편의상 제공됩니다. 전체 시스템의 디자인 변경을 제안하여이 특정 문제를 해결하려고하지 마십시오. 이 예제의 존재 여부는 원래 질문을 변경하지 않습니다.

일부 기존 코드는 정적 클래스의 존재 여부에 따라 다릅니다.

public static class ColorScheme
{
   ...
}

이 색 구성표는 Outlook 2003 색 구성표입니다. Outlook 2003 색 구성표를 유지하면서 Outlook 2007 색 구성표를 도입하고 싶습니다.

public static class Outlook2003ColorScheme
{
   ...
}

public static class Outlook2007ColorScheme
{
   ...
}

그러나 코드가 ColorScheme이라는 정적 클래스의 존재에 의존한다는 사실에 여전히 직면하고 있습니다. 내 첫 번째 생각은 Outlook2003 또는 Outlook2007에서 내려올 ColorScheme 클래스를 만드는 것이 었습니다.

public static class ColorScheme : Outlook2007ColorScheme
{
}

그러나 정적 클래스에서 내려갈 수는 없습니다.

내 다음 생각은 정적 ColorScheme 클래스를 만들면서 Outlook2003ColorScheme 및 Outlook2007ColorScheme 클래스를 비 정적으로 만드는 것이 었습니다. 그러면 정적 ColorScheme 클래스의 정적 변수가 "true"색 구성표를 가리킬 수 있습니다.

public static class ColorScheme
{
    private static CustomColorScheme = new Outlook2007ColorScheme();
    ...
}

private class CustomColorScheme 
{ 
   ...
}

private class Outlook2008ColorScheme : CustomColorScheme 
{
    ...
}

private class Outlook2003ColorScheme : CustomColorScheme 
{
   ...
}

하지만 그렇게하려면 읽기 전용 정적 색상으로 구성된 클래스를 재정의 가능한 속성으로 변환해야합니다. 그러면 내 ColorScheme 클래스에 포함 된 개체에 30 개의 서로 다른 속성 게터가 있어야합니다.

그것은 너무 많은 타이핑입니다.

그래서 다음 생각은 클래스의 별칭을 지정하는 것이 었습니다.

public static ColorScheme = Outlook2007ColorScheme;

그러나 그것은 컴파일되지 않습니다.

정적 클래스를 다른 이름으로 어떻게 별칭을 지정할 수 있습니까?


업데이트 : 누군가 "You cannot do this in C #"을 추가해 주시면 수락 된 답변으로 표시 할 수 있습니다. 동일한 질문에 대한 답변을 원하는 다른 사람은이 질문, 허용 된 답변 및 유용 할 수도 있고 아닐 수도있는 여러 해결 방법을 찾을 수 있습니다.

이 질문을 종료하고 싶습니다.


원래 클래스 이름을 변경하면 가져 오기 별칭을 typedef대신 사용하여 종속 코드를 다시 작성할 수 있습니다 .

using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;

이것은 일반 usings 와 마찬가지로 파일 / 네임 스페이스의 맨 위에 있어야합니다 .

그래도 이것이 당신의 경우에 실용적인지 모르겠습니다.


다음 코드 줄을 추가하여 클래스의 별칭을 만들 수 있습니다.

using Outlook2007ColorScheme = YourNameSpace.ColorScheme;

요구 사항에 따라 ( Factory | Singleton )을 원합니다 . 전제는 클라이언트 코드가 어떤 색 구성표를 얻고 있는지 알 필요가 없도록 만드는 것입니다. 색 구성표가 적용 범위가 넓어야한다면 싱글 톤이 좋습니다. 다른 상황에서 다른 체계를 사용할 수 있다면 팩토리 패턴을 사용하는 것이 좋습니다. 어느 쪽이든 색 구성표를 변경해야 할 때 코드를 한 곳에서만 변경하면됩니다.

public interface ColorScheme {
    Color TitleBar { get; }
    Color Background{ get; }
    ...
}

public static class ColorSchemeFactory {

    private static ColorScheme scheme = new Outlook2007ColorScheme();

    public static ColorScheme GetColorScheme() { //Add applicable arguments
        return scheme;
    }
}

public class Outlook2003ColorScheme: ColorScheme {
   public Color TitleBar {
       get { return Color.LightBlue; }
   }

    public Color Background {
        get { return Color.Gray; }
    }
}

public class Outlook2007ColorScheme: ColorScheme {
   public Color TitleBar {
       get { return Color.Blue; }
   }

    public Color Background {
        get { return Color.White; }
    }
}

C #에서는 클래스 이름의 별칭을 지정할 수 없습니다.

C #에서 클래스 이름의 별칭을 지정하지 않고 수행 할 수있는 작업이 있습니다.

그러나 원래 질문에 답하려면 C #에서 클래스 이름을 별칭으로 지정할 수 없습니다.


업데이트 : 사람들은 왜 using작동하지 않는지 혼란스러워 합니다. 예:

Form1.cs

private void button1_Click(object sender, EventArgs e)
{
   this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}

ColorScheme.cs

class ColorScheme
{
    public static Color ApplyColorScheme(Color c) { ... }
}

그리고 모든 것이 작동합니다. 이제 클래스 를 만들고 별칭 을 만들고 싶습니다 ColorScheme( 코드를 수정할 필요가 없도록 ).

ColorScheme.cs

using ColorScheme = Outlook2007ColorScheme;

class Outlook2007ColorScheme
{
    public static Color ApplyColorScheme(Color c) { ... }
}

오, 미안 해요. 이 코드는 컴파일되지 않습니다.

여기에 이미지 설명 입력

내 질문은 C #에서 클래스의 별칭을 지정 하는 방법이었습니다 . 할 수 없습니다. C #에서 클래스 이름의 별칭을 지정 하지 않고 수행 할 수있는 작업이 있습니다 .

  • 에 따라 변화 모두 ColorSchemeusing ColorScheme대신 (코드 변경 해결 내가 별칭 수 없기 때문에)
  • ColorScheme팩토리 패턴을 사용하는 모든 사람을 다형성 클래스 또는 인터페이스로 변경하십시오 (별칭을 할 수 없기 때문에 코드 변경 해결 방법)

그러나 이러한 해결 방법에는 옵션이 아닌 기존 코드를 깨는 것이 포함됩니다.

If people depend on the presence of a ColorScheme class, i have to actually copy/paste a ColorScheme class.

In other words: i cannot alias a class name in C#.

This contrasts with other object oriented languages, where i could define the alias:

ColorScheme = Outlook2007ColorScheme

and i'd be done.


try this:

using ColorScheme=[fully qualified].Outlook2007ColorScheme

Aliasing the way that you would like to do it will not work in C#. This is because aliasing is done through the using directive, which is limited to the file/namespace in question. If you have 50 files that use the old class name, that will mean 50 places to update.

That said, I think there is an easy solution to make your code change as minimal as possible. Make the ColorScheme class a facade for your calls to the actual classes with the implementation, and use the using in that file to determine which ColorScheme you use.

In other words, do this:

using CurrentColorScheme = Outlook2007ColorScheme;
public static class ColorScheme
{
   public static Color ApplyColorScheme(Color c)
   {
       return CurrentColorScheme.ApplyColorScheme(c);
   }
   public static Something DoSomethingElse(Param a, Param b)
   {
       return CurrentColorScheme.DoSomethingElse(a, b);
   }
}

Then in your code behind, change nothing:

private void button1_Click(object sender, EventArgs e)
{
   this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}

You can then update the values of ColorScheme by updating one line of code (using CurrentColorScheme = Outlook2008ColorScheme;).

A couple concerns here:

  • Every new method or property definition will then need to be added in two places, to the ColorScheme class and to the Outlook2007ColorScheme class. This is extra work, but if this is true legacy code, it shouldn't be a frequent occurence. As a bonus, the code in ColorScheme is so simple that any possible bug is very obvious.
  • This use of static classes doesn't seem natural to me; I probably would try to refactor the legacy code to do this differently, but I understand too that your situation may not allow that.
  • If you already have a ColorScheme class that you're replacing, this approach and any other could be a problem. I would advise that you rename that class to something like ColorSchemeOld, and then access it through using CurrentColorScheme = ColorSchemeOld;.

I'm adding this comment for users finding this long after OP accepted their "answer". Aliasing in C# works by specifying the class name using it's fully qualified namespace. One defined, the alias name can be used within it's scope. Example.

using aliasClass = Fully.Qualified.Namespace.Example;
//Example being the class in the Fully.Qualified.Namespace

public class Test{

  public void Test_Function(){

    aliasClass.DoStuff();
    //aliasClass here representing the Example class thus aliasing
    //aliasClass will be in scope for all code in my Test.cs file
  }

}

Apologies for the quickly typed code but hopefully it explains how this should be implemented so that users aren't mislead into believing it cannot be done in C#.


I suppose you can always inherit from the base class with nothing added

public class Child : MyReallyReallyLongNamedClass {}

UPDATE

But if you have the capability of refactoring the class itself: A class name is usually unnecessarily long due to lack of namespaces.

If you see cases as ApiLoginUser, DataBaseUser, WebPortalLoginUser, is usually indication of lack of namespace due the fear that the name User might conflict.

In this case however, you can use namespace alias ,as it has been pointed out in above posts

using LoginApi = MyCompany.Api.Login;
using AuthDB = MyCompany.DataBase.Auth;
using ViewModels = MyCompany.BananasPortal.Models;

// ...
AuthDB.User dbUser;
using ( var ctxt = new AuthDB.AuthContext() )
{
    dbUser = ctxt.Users.Find(userId);
}

var apiUser = new LoginApi.Models.User {
        Username = dbUser.EmailAddess,
        Password = "*****"
    };

LoginApi.UserSession apiUserSession = await LoginApi.Login(apiUser);
var vm = new ViewModels.User(apiUserSession.User.Details);
return View(vm);

Note how the class names are all User, but in different namespaces. Quoting PEP-20: Zen of Python:

Namespaces are one honking great idea -- let's do more of those!

Hope this helps


Is it possible to change to using an interface?

Perhaps you could create an IColorScheme interface that all of the classes implement?

이것은 Chris Marasti-Georg가 보여주는 공장 패턴과 잘 작동합니다.


매우 늦은 부분적인 답변입니다. 그러나 동일한 네임 스페이스 'Outlook'에서 동일한 클래스 'ColorScheme'을 정의하지만 Outlook2003이라는 별도의 어셈블리와 다른 Outlook2007이라는 별도의 어셈블리를 정의하면 적절한 어셈블리를 참조하기 만하면됩니다. .

참고 URL : https://stackoverflow.com/questions/244246/how-do-i-alias-a-class-name-in-c-without-having-to-add-a-line-of-code-to -마다

반응형